Шукати в цьому блозі

вівторок, 20 грудня 2016 р.

Як розбити flac по наявному cue у Linux?

Як виявилося тема ця не нова. Найпростіший шлях такий. Встановлюємо:
sudo aptitude install cuetools shntool flac
Далі, припустимо у нас є наступні файли:
$ ls -1 Океан\ Ельзи\ -\ Без\ меж.*
Океан Ельзи - Без меж.cue
Океан Ельзи - Без меж.flac
Тоді розбити оригінальний flac на окремі композиції можна так:
$ cuebreakpoints Океан\ Ельзи\ -\ Без\ меж.cue | \
  shnsplit -o flac Океан\ Ельзи\ -\ Без\ меж.flac
Після чого отримуємо наступний список файлів:
$ ls -1 split-track*
split-track01.flac
split-track02.flac
split-track03.flac
split-track04.flac
split-track05.flac
split-track06.flac
split-track07.flac
split-track08.flac
split-track09.flac
split-track10.flac
split-track11.flac
Окремий файл - окрема композиція.
Але є певна проблема, у отриманих файлах відсутня інформація про виконавця, альбом, тощо. Це не зовсім зручно, якщо збираємося додати ці файли у сучасні медіаплеєри, які вміють читати ці метадані.

Покроково.
Кількість композицій:
$ cueprint -d '%N' Океан\ Ельзи\ -\ Без\ меж.cue
11
Метадані по композиції №1:
$ cueprint -n 1 Океан\ Ельзи\ -\ Без\ меж.cue | iconv -f cp1251
Track 1 Information
arranger: 
composer: 
genre:  
ISRC:  
message: 
track number: 1
perfomer: Океан Ельзи
title:  Віддай мені (свою любов)
ISRC (CD-TEXT): 
або у заданому форматі:
$ cueprint -n 1 -t \
  'ARRANGER=%A\nCOMPOSER=%C\nGENRE=%G\nMESSAGE=%M\nTRACKNUMBER=%n\nARTIST=%p\nTITLE=%t\nALBUM=%T\n' \
  Океан\ Ельзи\ -\ Без\ меж.cue | \
  iconv -f cp1251
ARRANGER=
COMPOSER=
GENRE=
MESSAGE=
TRACKNUMBER=1
ARTIST=Океан Ельзи
TITLE=Віддай мені (свою любов)
ALBUM=Без меж

Всі ці моменти можна об'єднати у скрипт. Проект можна завантажити звідси splitflac.

UPDATE:
Був отримав помилку:
shnsplit: error: m:ss.ff format can only be used with CD-quality files
Таблетка:
cuebreakpoints *.cue | sed s/$/0/ | shnsplit -t %n -o flac *.flac

четвер, 27 жовтня 2016 р.

RouterOS та передача маршрутної інформації у DHCP

Певно, що тим, хто читає цей нотаток, відомо, що у DHCP можна передавати окрім всього іншого й маршрутну інформацію. Тут розглянемо як це робиться у RouterOS та намалюємо маленький скрипт який допоможе в цій роботі у подальшому.

RFC3442 має назву The Classless Static Route Option for Dynamic Host Configuration Protocol (DHCP) version 4 і описує формат опції 121, в якій передається маршрутна інформація. Для тієї самої задачі слугує й опція 249, але про неї окремо.

Формат опції у RFC виглядає так:
  Code Len Destination 1    Router 1
   +-----+---+----+-----+----+----+----+----+----+
   | 121 | n | d1 | ... | dN | r1 | r2 | r3 | r4 |
   +-----+---+----+-----+----+----+----+----+----+

    Destination 2       Router 2
   +----+-----+----+----+----+----+----+
   | d1 | ... | dN | r1 | r2 | r3 | r4 |
   +----+-----+----+----+----+----+----+
Тобто маємо безпосередньо код опції, наступний байт це кількість мережевих бітів (маска мережі), потім йдуть октети, що описують номер мережі та 4 байти/октети, що описують маршрутизатор через який має бути побудовано маршрут. Також у RFC читаємо, що для декількох маршрутів вони можуть бути склеєні.

Окрему увагу заслуговує кількість Destination октетів. У RFC можна побачити наступне:
        Width of subnet mask     Number of significant octets
                     0                     0
                  1- 8                     1
                  9-16                     2
                 17-24                     3
                 25-32                     4
Це все справедливо як для опції 121 так і для опції 249. Єдине зауваження щодо опції 249, яке знайшов на хабрі, те, що до маршрутної інформації варто додавати 00[адреса шлюзу]. Пишуть, що це справедливо для комп'ютерів під керуванням ОС Windows.

Все це була не дуже цікава, але не менш важлива теорія, приступимо до практики.

Озброївшись знаннями з RFC3442 можна доволі швидко написати додаток, що буде обчислювати маршрути й формувати відповідний вивід. Я полюбляю Perl тому скрипт було написано саме на ньому, https://github.com/oldengremlin/route-4-dhcp/blob/master/rfc3442.route-4-dhcp.pl:

Поставимо на меті описати маршрут на мережі RFC1918 через /dev/null. Взагалі то було б непогано змаршрутизувати їх через 127.0.0.1, але ж через описані опції маршрути можуть бути додано лише через ті адреси до яких клієнт може знати як дістатися. Тому, припустимо, що у нашій мережі 192.168.88.0/24 не існує хоста 192.168.88.2, а трафік пустимо через нього.

Назвемо скрипт rfc3442.route-4-dhcp та запустимо його з параметрами:
$ rfc3442.route-4-dhcp 10.0.0.0/8 192.168.88.2 172.16.0.0/12 192.168.88.2 192.168.0.0/16 192.168.88.2
option_121_route_10.0.0.0/8_via_192.168.88.2 : 0x080ac0a85802
option_249_route_10.0.0.0/8_via_192.168.88.2 : 0x080ac0a85802
option_121_route_172.16.0.0/12_via_192.168.88.2 : 0x0cac10c0a85802
option_249_route_172.16.0.0/12_via_192.168.88.2 : 0x0cac10c0a85802
option_121_route_192.168.0.0/16_via_192.168.88.2 : 0x10c0a8c0a85802
option_249_route_192.168.0.0/16_via_192.168.88.2 : 0x10c0a8c0a85802
aggregate_opt_121 : 0x080ac0a858020cac10c0a8580210c0a8c0a85802
aggregate_opt_249 : 0x080ac0a858020cac10c0a8580210c0a8c0a85802

Передаємо скрипту пари у вигляді мережа-шлюз і отримуємо попарний вивід для окремих мереж і останніми строками сукупну маршрутну інформацію для всіх мереж.

Тепер перенесемо всю цю інформацію у RouterOS:
/ip dhcp-server option
add code=121 name=aggregate_opt_121_over_fakeip_192.168.88.2 value=0x080ac0a858020cac10c0a8580210c0a8c0a85802
add code=249 name=aggregate_opt_249_over_fakeip_192.168.88.2 value=0x080ac0a858020cac10c0a8580210c0a8c0a8580200c0a85801

Щодо опції 249 читаємо зауваження нагорі і дивимося як було додано маршрут через основну адресу маршрутизатора - 192.168.88.1.

Опції задано, тепер їх можна додати у список опцій у описі мережі в налаштуваннях dhcp-серверу. Якщо у dhcp-сервері вже було налаштовано передачу інформації щодо wpad то разом з маршрутною інформацією команда налаштування мережі може виглядати якось так:
/ip dhcp-server network
add address=192.168.88.0/24 comment=dhcp-server dhcp-option=\
    auto-proxy-config,aggregate_opt_121_over_fakeip_192.168.88.2,aggregate_opt_249_over_fakeip_192.168.88.2,disable_nbt dns-server=\
    192.168.88.1 gateway=192.168.88.1 netmask=24 ntp-server=192.168.88.1

Домашнім завданням може бути написання скрипту якій розшифровує 0x080ac0a858020cac10c0a8580210c0a8c0a85802 у зворотньому напрямку ;)

середу, 26 жовтня 2016 р.

RouterOS та налаштування Proxy через DHCP

Рік тому публікував тут як налаштувати прозорий web-proxy на Мікротиці. Але сталося, що частині комп'ютерів, які це вміють, треба було якось віддавати налаштування щодо proxy автоматично.

Для isc dhcp серверу було знайдено опис щодо option 252, через яку можна налаштувати Web Proxy Autodiscovery Protocol (надалі wpad). Зазвичай налаштовується якось так:
option wpad code 252 = text;
option wpad "http://192.168.xxx.xxx/wpad.dat";
де http://192.168.xxx.xxx/wpad.dat вказує на файл налаштувань проксі.

Того самого ефекту можна досягнути у RouterOS наступним чином. Додаємо налаштування dhcp-опції та додаємо її до налаштувань мережі у dhcp-server-і:
/ip dhcp-server option add code=252 name=auto-proxy-config value="'http://192.168.xxx.xxx/wpad.dat'"
/ip dhcp-server network … dhcp-option=auto-proxy-config
Після додання опції клієнти які підтримують wpad автоматично завантажать wpad.dat та застосують налаштування з нього.

Приклад вмісту доволі простого wpan.dat:
// Функція використання проксі
function FindProxyForURL(url, host)
{
    // якщо текстове ім'я хоста без точок, то з'єднуємо з ним безпосередньо (корисно для локальних адрес)
    if (isPlainHostName(host)) { return "DIRECT"; }

    // якщо хост в мережі 192.168.88.0/24 або в мережі 127.0.0.0/8 то до нього підключаємося напряму
    if (isInNet (host, "192.168.88.0", "255.255.255.0") || isInNet (host, "127.0.0.0", "255.0.0.0")) { return "DIRECT"; }

    // якщо жодна умова не виконується - повертаємо ім'я проксі
    return "PROXY 192.168.88.1:8080; DIRECT";
}

Доступні наступні функції:

isResolvable(host) — запит імені хоста (перевірка існування) на DNS-сервері.
Приклад:
if (isResolvable(host))

dnsResolve(host) — запит DNS-сервера для перекладу імені в IP.
Приклад:
if (dnsResolve(host) == "xxx.xxx.xxx.xxx")

myIpAddress() — повертає IP-адреса (що складається з цілих чисел і точок) вузла, на якому запущений браузер.
Приклад:
if (myIpAddress() == "xxx.xxx.xxx.xxx")

isPlainHostName(host) — перевіряє, чи містяться точки в імені вузла. якщо точка знайдена, то повертається значення false; якщо немає, повертається значення true.
Приклад:
if (isPlainHostName(host))

dnsDomainLevels(host) — повертає ціле число, яке дорівнює кількості точок в імені вузла.
Приклад:
if (dnsDomainLevels(host) > 0)

dnsDomainIs(host, ".company.com") — повертає значення true, якщо домен з імені вузла збігається з заданим доменом.
Приклад:
if (isPlainHostName(host) || dnsDomainIs(host, ".company.com"))

localHostOrDomainIs(host, "www.company.com") — повертає значення true, якщо домен з імені вузла збігається з заданим доменом. Виконується тільки для URL-адрес, що відносяться до локального домену.
Приклад:
if (!localHostOrDomainIs(host, "www.company.com"))

shExpMatch(str, shexp) — повертає значення true, якщо str відповідає шаблоном оболонки shexp.
Приклад:
if (shExpMatch(host, "*.com"))

isInNet(host, pattern, mask) — повертає значення true, якщо IP-адреса вузла відповідає зазначеному шаблоном (наприклад, 127.0.0.0). mask вказує, яку частина IP-адреси слід зіставляти (255 = зіставляти, 0 = ігнорувати).
Приклад:
if (isInNet(host, "999.99.9.9", "255.0.255.0"))

url.substring(0, n) — витягує вказану кількість знаків з початку рядка
Приклад:
url.substring(0, 4)

weekdayRange( day1 [, day2] [,"GMT"] ) — повертає значення true, якщо поточний
час системи потрапляє в діапазон, заданий з використанням параметрів і необов'язковий параметр GMT вказує, якщо задано не місцевий час, а час за Гринвічем.
Приклад:
if(weekdayRange("WED", "SAT", "GMT"))

dateRange(day1 [,month1] [,year1] [,day2] [,month2] [,year2] [,gmt] )
day — число дня місяцю між 1 и 31;
month — місяць: JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC;
year — повний (чотиризначний) рік;
gmt — зона GMT (по Гринвічу).
Приклад:
dateRange (1) // true якщо сьогодні перше число, використовується локальний час.
dateRange (1, "GMT") // true сьогодні перше число, використовується час за Гринвічем.
dateRange (1, 15) // true якщо сьогодні число в діапазоні від 1 до 15-е.
dateRange (24, "DEC") // true кожне 24-е грудня.
dateRange (24, "DEC", 1995) // true якщо сьогодні 24е-е грудня 1995 року.
dateRange ( "JAN", "MAR") // true з січня по березень
dateRange (1, "JUN", 15, "AUG") // true з 1 червня по 15-е серпня (включно).
dateRange (1, "JUN", 15, 1995, "AUG", 1995) // true з 1-го червня 1995 року по 15-е червня 1995 року.
dateRange ( "OCT", 1995, "MAR", 1996) // true з жовтня 1995 по березень 1996 (включно).
dateRange (1995) // true протягом 1995 року.
dateRange (1995, 1997) // true з 1995 до 1997

timeRange(hour1 [,min1] [,sec1] [,hour2] [,min2] [,sec2] [,gmt] )
hour — час від 0 до 23;
min — хвилини від 0 до 59;
sec — секунди від 0 до 59;
gmt — зона GMT (по Гринвічу).
Приклад:
timerange (12) // true до 13:00.
timerange (12, 13) // true з 12:00 до 13:00.
timerange (12, "GMT") // true з початку для до 13:00 за Гринвічем.
timerange (9, 17) // true from 9am to 5pm.
timerange (8, 30, 17, 00) // true з 8:30 to 17:00.
timerange (0, 0, 0, 0, 0, 30) // true з півночі і до 00:00:30 секунд.

Також ще підтримуються змінні.
Приклад:
ip_host  = dnsResolve(host);
ip_localnet = "192.168.0.0";
ip_localhost = "127.0.0.1";
proxy_general = "PROXY gwhost.my:3128";
proxy_local = "PROXY localhost:3128";

четвер, 15 вересня 2016 р.

Налаштування IPv6 у RouterOS як клієнта для SLAAC+DHCPv6

Багато статей є про те як налаштувати IPv6 у RouterOS через тунель-брокера. Але мало де написано про те як налаштувати IPv6 у RouterOS коли підключення відбувається за схемами SLAAC, SLAAC+DHCPv6… Спробуємо виправити цей недолік.

Про те, що уявляє з себе функціонал SLAAC, SLAAC+DHCPv6 та DHCPv6 можна прочитати, наприклад, тут.

Так от, наш провайдер надає нам IPv6 за схемою SLAAC+DHCPv6: надає нам /64 на підключенні та делегує якусь мережу, щоб ми могли її вже роздати у себе. Ми будемо у себе реалізовувати лише функціонал SLAAC.

Невелике зауваження, наразі налаштовано та протестовано RouterOS версії 6.36.3. Рік тому була інша версія і синтаксис щодо налаштувань, з того часу, дещо змінився.

Налаштовуємо RouterOS:

/ipv6 nd set [ find default=yes ] advertise-dns=yes interface=bridge-local ra-interval=1m40s-3m20s
/ipv6 dhcp-client add add-default-route=yes interface=ether1-gateway pool-name=v6pool request=address,prefix
/ipv6 address add eui-64=yes from-pool=v6pool interface=bridge-local
/ipv6 address add address=fec0:0:0:ffff::1/10 advertise=no interface=bridge-local
/ipv6 address add address=fec0:0:0:ffff::2/10 advertise=no interface=bridge-local
/ipv6 address add address=fec0:0:0:ffff::3/10 advertise=no interface=bridge-local

ND

За замовченням ND interface дивиться у all, тобто на всі інтерфейси. Ми ж не хочемо роздавати той сервіс, що отримаємо, назовні, хочемо роздати тільки своїм абонентам, тому вносимо відповідні правки у конфігурацію за замовченням. Так як видалити її не можна то робиться саме встановлення властивостей у наявну конфігурацію. Можна було б зробити її неактивною й додати нову, але, як на мене, наведений шлях більш вірний.

Для ND встановлюємо внутрішній інтерфейс. Кажемо про те, що маємо оповіщати в мережу наявні DNS. Опції managed-address-configuration  та other-configuration не встановлюємо, звісно якщо не хочемо реалізувати схему відмінну від чистого SLAAC.

DHCPv6 клієнт

Далі, налаштовуємо dhcpv6 клієнта на зовнішньому інтерфейсі. Кажемо, що отримана інформація має використовуватися для встановлення маршруту за замовченням, а також має динамічно організуватися пул префіксів IPv6 які були делеговані нам від провайдера.

IPv6 адреса на локальному інтерфейсі

Наступним кроком налаштовуємо внутрішній інтерфейс таким чином щоб він брав адрес з організованого пулу та формував його за eui-64. Хтось захоче інакше, скаже, що це небезпечно, не питання, можна й інакше:
/ipv6 address add from-pool=v6pool address=::1/64 interface=bridge-local

Клієнти у локальнїй мережі

Зауваження щодо Windows

Якщо явно не вказати ОС Windows що треба використовувати IPv6-unicast DNS-сервери то за замовченням запити будуть відправлятися до спеціальних site-local адрес fec0:0:0:ffff::1, fec0:0:0:ffff::2 та fec0:0:0:ffff::3. Також DNS можна вказати вручну, використовуючи netsh.

Підтримка fec0:0:0:ffff::1, fec0:0:0:ffff::2 та fec0:0:0:ffff::3

Підтримку адрес fec0:0:0:ffff::1, fec0:0:0:ffff::2 та fec0:0:0:ffff::3 можна організувати на Mikrotik, наприклад, так як наведено вище:
/ipv6 address add address=fec0:0:0:ffff::1/10 advertise=no interface=bridge-local
/ipv6 address add address=fec0:0:0:ffff::2/10 advertise=no interface=bridge-local
/ipv6 address add address=fec0:0:0:ffff::3/10 advertise=no interface=bridge-local

Статичне встановлення DNS серверів

Також DNS-сервери для IPv6 можна встановити статично. Наприклад 6-to-4:
netsh interface ipv6 add dnsservers 10 index=1 2001:4860:4860::6464
netsh interface ipv6 add dnsservers 10 index=2 2001:4860:4860::64
та/або публічні google DNS:
netsh interface ipv6 add dnsservers 10 index=3 2001:4860:4860::8888
netsh interface ipv6 add dnsservers 10 index=4 2001:4860:4860::8844
або ж адреси які надає провайдер.

Disabling RFC 4941 IPv6 Privacy Extensions in Windows

За замовченням Windows періодично генерить нову IPv6 адресу у разі чого деякі ресурси у мережі починають лаятись на те, що у користувача змінилася адреса і припиняють коректно працювати. Лікується це просто і не потребує перезавантаження:
netsh interface ipv6 set global randomizeidentifiers=disabled store=persistent
netsh interface ipv6 set privacy randomizeidentifiers=disabled store=persistent
Але знов-таки eui-64…

Зауваження щодо Linux

З Linux також все просто. Кажемо:
sysctl net.ipv6.conf.eth0.accept_ra=1
sysctl net.ipv6.conf.eth0.autoconf-1
sysctl net.ipv6.conf.eth0.hop_limit=64
І у налаштуваннях мережі кажемо, що для IPv6 налаштування мають отримуватися автоматично. Не забудьте про hop_limit! Чомусь у Debian-і за замовченням він був встановлений у 0, від чого, коли робився ping6, отримували повідомлення: "Time exceeded: Hop limit".

середу, 13 липня 2016 р.

RouterOS/Mikrotik: гостьове підключення та боротьба з халявщиками.

Організувати на Mikrotik гостьовий wifi це справа добра, але, як загальновідомо, шара об'єму не має то завжди окрім мобільних пристроїв (проти яких ніхто особливо нічого не має) з'являються халявщики з ноутбуками, які вважають, що торенти на гостьовому це норма. Ні, не норма.

Тобто, мета, залишити доступ для будь-яких Android, iPhone, WindowsPhone і, по можливості, блокувати будь-яких інших "абонентів".

Все це робимо на Mikrotik 2011UiAS-2HnD, хоча певно без зайвих зусиль перенесеться та підійде до будь-яких інших моделей.

Рецепт, у скриптах.

Скрипт dhcp-make-static-guest:

/ip dhcp-server lease make-static [ find server="guest" and address!="guest-dhcp" ];
/ip dhcp-server lease set [ find server="guest" and address!="guest-dhcp" ] address="guest-dhcp" always-broadcast=no;
Тобто для dhcp серверу, який обслуговує guest підключення, всі підключення у lease робляться статичними. Другим кроком, всім їм замість статичної адреси призначається адресний пул, в який розрахований для гостьових підключень. Таким чином при кожному наступному підключення гість має можливість отримати будь-яку іншу адресу з пулу і не конфліктувати з іншими. Якби адреса була статичною то велика вірогідність, що адреси б, наприклад, збігалися.
Скрипт dhcp-make-static-guest варто запускати за розкладом, але не рідше ніж виділено lease time.
Далі, для статичних гостьових записів у dhcp lease проводимо регламентну обробку, а саме:

  • блокуємо доступ для записів у яких hostname є пустим;
  • блокуємо доступ для записів у яких запис не відповідає певним ознакам (наприклад всі Android пристрої мають hostname який починається з android).
Скрипт reglament:
:foreach i in=[/ip dhcp-server lease find server="guest"] do={

  :local mac [/ip dhcp-server lease get $i mac-address];
  :local hostname [/ip dhcp-server lease get $i host-name];
  :local blockaccess [/ip dhcp-server lease get $i block-access];
  :local lenhostname [ :len $hostname ];

  :if ($lenhostname<1) do={
    # Block Access for Hosts whith empty hostname.

    /ip dhcp-server lease set [ find mac-address=$mac ] block-access=yes

  } else={
    # Block Access for another categories.

    :local hn;
    :local illegal true;

    if ($illegal) do={
      :set hn [ :pick $hostname 0 7 ];
      if ([ :find $hn "android" -1 ]=0) do={
        :set illegal false;
      }
    }

    if ($illegal) do={
      :set hn [ :pick $hostname 0 7 ];
      if ([ :find $hn "Windows" -1 ]=0) do={
        :set illegal false;
      }
    }

    if ($illegal) do={
      :set hn [ :pick $hostname 0 6 ];
      if ([ :find $hn "iPhone" -1 ]=0) do={
        :set illegal false;
      }
    }

    if ($illegal) do={
      :set hn [ :pick $hostname 0 4 ];
      if ([ :find $hn "iPad" -1 ]=0) do={
        :set illegal false;
      }
    }

    if ($illegal) do={
      :set hn [ :pick $hostname 0 9 ];
      if ([ :find $hn "Microsoft" -1 ]=0) do={
        :set illegal false;
      }
    }

    if ($illegal) do={
      :set hn [ :pick $hostname 0 10 ];
      if ([ :find $hn "BLACKBERRY" -1 ]=0) do={
        :set illegal false;
      }
    }

    if ($illegal && !$blockaccess) do={
      :put "Block-Access: $mac $blockaccess";
      /ip dhcp-server lease set [ find mac-address=$mac ] block-access=yes
    }

  }
}
Додаємо виклик цих скриптів у розклад:
/system scheduler add interval=2m30s name=reglament on-event="/system script run dhcp-make-static-guest ;\r\
    \n/system script run reglament ;\r\
    \n" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive start-date=jan/01/1970 start-time=00:00:00

На додаток, також можна спробувати додати деяких "незручностей" халявщикам, що бажають тягати великі файли через гостьове підключення. Скажемо у reglament додати:
# Disable guest subscribers who exceed the limit for a single connection.
:foreach wirelessClient in [/interface wireless registration-table find  interface="wlan2-guest" ] do={
  :local macAddress [/interface wireless registration-table get [ find .id=$wirelessClient ] value-name=mac-address];
  :local bytes [/interface wireless registration-table get [ find .id=$wirelessClient ] value-name=bytes];
  :local posComma [ :find $bytes "," -1];
  :local RXbytes [:pick $bytes 0 $posComma];

  :local deregister false;
  :if ($RXbytes > 20000000) do={ 
    :set deregister true;
  }
  if (deregister) do={
    :put "Deregistration: $macAddress $bytes $RXbytes";
    /interface wireless registration-table remove [ find mac-address=$macAddress ]
  }
}
Тут ми "рубаємо" всі wifi-підключення по яким пройшло/прийнято більше 20 мільйонів байт. Повірте, що жодна web-сторінка за одну сесію не віддасть такий обсяг інформації. Ну, а кому треба то той перепідключиться до гостьового доступу. Принаймні більша частина сучасних пристроїв та операційних систем це робить автоматично.

вівторок, 24 травня 2016 р.

regexp - тільки номери мобільних операторів України.

Постало питання перевіряти номери телефонів на відповідність до будь-якого мобільного оператора України. Орієнтуючись на коди операторів, станом на травень 2016, вийшов от такий регулярний вираз:
^(\+?38)?0[ -]*(((50|6[3678]|73|9[1-9])[ -]*[0-9]{3}[ -]*[0-9]{2}[ -]*[0-9]{2})|(89[ -]*[1-9][0-9]{2}[ -]*[0-9]{2}[ -]*[0-9]{2}))$
Номер має бути представлений у форматах +380 XX XXX XX XX або 0XX XXX XX XX.
Для зручності:
^(\+?38)?0[ -]*(
((50|6[3678]|73|9[1-9])[ -]*[0-9]{3}[ -]*[0-9]{2}[ -]*[0-9]{2})|
(89[ -]*[1-9][0-9]{2}[ -]*[0-9]{2}[ -]*[0-9]{2})
)$
Коди мобільних операторів України бралися з Wikipedia.

вівторок, 19 квітня 2016 р.

Сортування ip-адрес у консолі

Постало питання у виводі на консоль відсортувати ip-адреси (v4). Виявилося, що це робиться доволі просто, через стандартну команду sort:
$ nmap -sP 10.100.1.* 2>&1 >/dev/null
$ ip neigh show | \
  awk '$4~/^INCOMPLETE$/ { print $1 }' | \
  sort -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n

  • -t . : Set field to . (dot) as our IPs separated by dot symbol;
  • -n : Makes the program sort according to numerical value;
  • -k opts: Sort data / fields using the given column number. For example, the option -k 2 made the program sort using the second column of data. The option -k 3,3n -k 4,4n sorts each column. First it will sort 3rd column and then 4th column.

середу, 16 березня 2016 р.

Debian: встановлення Adobe Reader

Завантажуємо Adobe Reader 9.5.5 enu (AdbeRdr9.5.5) і встановлюємо acroread.
wget http://ardownload.adobe.com/pub/adobe/reader/unix/9.x/9.5.5/enu/AdbeRdr9.5.5-1_i386linux_enu.deb
sudo aptitude install gdebi
sudo gdebi AdbeRdr9.5.5-1_i386linux_enu.deb
acroread
Варто зауважити, що Adobe припинила випуски та підтримку acroread-ера для Linux.

понеділок, 14 березня 2016 р.

Gnome3 - іконки на робочій стільниці

Як можна помітити, то за замовченням gnome3 не висвітлює на робочій стільниці жодних іконок. Але цю поведінку можна змінити.
Для цього нам знадобиться… правильно - консоль!
Запустимо gsettings та збережемо, про всяк випадок, всі поточні налаштування:
gsettings list-recursively | tee gsettings.keys.bak
Що ж до задачі висвітлення іконок на робочій стільниці gnome3 нас цікавлять:
gsettings get org.gnome.desktop.background show-desktop-icons
gsettings get org.gnome.nautilus.desktop volumes-visible
Ключ show-desktop-icons у схемі org.gnome.desktop.background та ключ volumes-visible у схемі org.gnome.nautilus.desktop треба встановити у значення true щоб отримати бажаний результат.
# show files on desktop
gsettings set org.gnome.desktop.background show-desktop-icons true

# show shares on desktop
gsettings set org.gnome.nautilus.desktop volumes-visible true

# restart nautilus
nautilus -q
nautilus
Створювати та редагувати посилання до додатків можна за допомогою додатку gnome-desktop-item-edit.

Gnome3 - початковий автоматичний запуск додатків

При спробі знайти засіб для налаштування автоматичного запуску додатків при вході у gnome3 google наполегливо відсилає нас на сторінки де рекомендується застосувати
gnome-session-properties
але треба зауважити, що цей додаток є застарілим. Замість нього можна використати
gnome-tweak-tool
де можна перейти у пункт "Початкові програми". Але, завжди є але. А якщо хочеться додати те чого немає у наданому меню? Тоді все також доволі просто - консоль! Переходимо у
cd .config/autostart/
і створюємо desktop-файл з описом додатка. Наприклад - xkb-lang.desktop:
[Desktop Entry]
Exec=/home/olden/bin/xkb-lang.sh
Hidden=true
Name=XKB-Lang
Icon=xterm
Terminal=false
Type=Application
X-GNOME-Autostart-enabled=true
Якщо після цього зайти у gnome-tweak-tool то можна побачити, що цей додаток буде відтворюватись у меню "Початкових програм" і, відповідно, буде запускатися при вході у gnome3.

пʼятницю, 11 березня 2016 р.

bash та sin, cos, тощо…

Рецепти для bash-а. Може кому знадобиться, от як мені…
function sin(){ echo "scale=10; s($1*a(1)/45);" | bc -l; }
function cos(){ echo "scale=10; c($1*a(1)/45);" | bc -l; }
function tan(){ echo "scale=10; arg=$1*a(1)/45; s(arg)/c(arg);" | bc -l; }
function ln(){ echo "scale=10; l($1);" | bc -l; }
function log(){ echo "scale=10; l($1)/l(10);" | bc -l; }
Правда народ ще більше страждає… ряди розписує:
function sin()
{
  if [ $# != 2 ]
  then
    echo "FAIL" >&2
    return 2
  fi

  result=$1
  x=$1
  n=1
  fact=1
  for k in `seq 2 $2`
  do
    x=$(( $x * $1 * $1 ))
    n=$(( $n + 2 ))
    fact=$(( (-1.0) * $fact * ($n - 1) * $n ))
    result=$(( $result + $x / $fact ))
  done
  echo $result
}

Debian: перехід з network interfaces на network-manager та налаштування vlan-ів.

Нещодавно все ж таки оновив wheezy на jessy і так сталося, що аж закортіло поміняти звичні налаштування у /etc/network/interfaces на те, що прпонує network-manager.

Раніше (давно, ой як давно) від цього кроку суттєво стримала відсутність підтримки vlan (чи то просто не помічав?). Але цього разу помітив її у gui від gnome, і вирішив більш досконало покопатися та зрозуміти що до чого, якщо захочеться лапками підправити.

Для початку, наш погляд має змінити напрямок з /etc/network/ на /etc/NetworkManager/, саме в останній директорії знаходяться всі налаштування щодо network-manager-а.

Головний файл налаштувань NetworkManager.conf залишився таким яким був за-замовченням. Найбільш цікаво це налаштування інтерфейсів. Інтерфейси описуються тут /etc/NetworkManager/system-connections, окремими файлами. Так, так, коли інтерфейси описується у gui network-manager-а то зберігаються вони саме тут.

Але від слів до діла. Припустимо, що нам треба налаштувати vlan7 зі статичною ip-адресою.

От як це виглядало б у interfaces:
auto vlan7
iface vlan7 inet static
        vlan_raw_device eth0
        address 93.124.120.14
        netmask 255.255.255.240
        gateway 93.124.120.1
        network 93.124.120.0
        broadcast 93.124.120.15
От як ті самі налаштування виглядатимуть у network-manager-і, додаємо файл /etc/NetworkManager/system-connections/vlan7 наступного змісту:
[connection]
id=VLAN7
uuid=6b5a8896-a4ab-4993-82b0-ce6739e389b7
interface-name=vlan7
type=vlan
timestamp=1457621961

[ipv6]
method=auto
ip6-privacy=0

[vlan]
interface-name=vlan7
parent=eth0
id=7

[ipv4]
method=manual
dns=211.89.160.2;211.89.160.8;
address1=93.124.120.14/28,93.124.120.1
Так, писати, якщо це робити вручну, стало трішки більше.
Що ми зробили? Описали секції для інтерфейсу за яким здійснюється з'єднання (connection), опції протоколів ipv6 та ipv4, та секцію яка описує наш vlan.

uuid у секції connection можна згенерувати за допомогою uuidgen (пакет uuid-runtime), він має бути унікальним.

Цікавим моментом є те, що до налаштувань можна одразу додати інформацію щодо маршрутів. Трішки змінимо секцію ipv4:
[ipv4]
method=manual
dns=211.89.160.2;211.89.160.8;
address1=93.124.120.14/28,93.124.120.1
route1=172.16.1.0/29,93.124.120.2
route2=10.254.0.0/16,93.124.120.2
route3=10.255.0.0/16,93.124.120.2
Тепер, наш хост знає, що шукати мережі 172.16.1.0/29, 10.254.0.0/16 та 10.255.0.0/16 треба не по маршруту за-замовченням, а через інший хост 93.124.120.2, який входить до мережі 93.124.120.0/28.

Ніякої потойбічної магії. Всі опції та поля задокументовані і не є якоюсь таємницею.

Останнє, у тому випадку якщо зміни які було внесено через gui одразу ж не застосовуються, треба просто переініціалізувати відповідний сервіс:
sudo service network-manager force-reload
От і все. Не настільки загадково, як здавалося на перший погляд ;)

середу, 9 березня 2016 р.

Debian Upgrade та повне відновлення KDE або Gnome

Нарешті оновився з wheezy на jessie, але при цьому повністю за залежностями зламався kde. Постало питання, а як же оновити kde та/або gnome якщо вони "зламалися"?
Відповідь, як завжди, лежить у Debian Wiki.
sudo aptitude install ~t^desktop$ ~t^kde-desktop$
sudo tasksel -t install gnome-desktop
sudo aptitude -q --without-recommends \
    -o APT::Install-Recommends=no -y \
    install ~t^desktop$ ~t^gnome-desktop$
Для KDE можна спробувати щось на кшталт такого як і для Gnome:
sudo tasksel -t install kde-desktop
sudo aptitude -q --without-recommends \
    -o APT::Install-Recommends=no -y \
    install ~t^desktop$ ~t^kde-desktop$

понеділок, 7 березня 2016 р.

Тестування SMTP та ESMTP через telnet

SMTP (Simple Mail Transfer Protocol, Простий Протокол Пересилання Пошти) - це протокол, який використовується для пересилання електронної пошти до поштового сервера або з клієнта-комп'ютера, або між поштовими серверами. В IANA для SMTP зареєстрований порт 25. SMTP з'єднання де застосовується SSL шифрування використовують порт 465. Формально SMTP визначений в RFC 821 (STD 10) та покращений RFC 1123 (STD 3) розділ 5. Протокол, який використовується зараз, також відомий як ESMTP і визначений в RFC 2821.

Окрім з'єднань між MTA (Mail Transfer Agent), зі сторони клієнта з'єднатися з smtp-сервером можна як за допомогою налаштованого MUA (Mail User Agent) так і за допомогою telnet на 25/tcp порт. Щоб швидко перевірити чи smtp-сервер взагалі слухає та хоч якось працює останнього цілком достатньо.

Перевіряємо SMTP.
telnet сервер 25
Після того як з'єднання з smtp-сервером буде встановлено і отримаємо привітання, щось на кшталт
220 smtp.server.com, ESMTP
Можна спробувати ввести одна за одною наступні smtp-команди:
HELO localhost
MAIL FROM: <sender@server.com>
RCPT TO: <user1@server.com>
RCPT TO: <user2@server.com>
DATA
From: Sender <sender@server.com>
To: Receiver1 <user1@server.com>
To: Receiver2 <user2@server.com>
Subject: Test SMTP
Content-Type: text/plain

Hi!
Test SMTP.

.
QUIT
Варто зауважити, що якщо ви не є визнаним користувачем smtp-сервера (наприклад, абонентом провайдера до smtp-сервера якого хочете отримати доступ) то smtp-сервер може або не прийняти з'єднання або ж на будь-якому етапі перервати його, якщо таку дію налаштовано задля забезпечення унеможливлювання пересилання спаму.

Іноді, але не завжди, smtp-сервера для своїх користувачів надають можливість надсилати пошту з будь-якої частини Мережі, за умови позитивного проходження аутентифікації. Аутентифікація є розширенням до протоколу SMTP. Для її перевірки попередньо знадобиться виконати дві команди: перша ідентифікую користувача сервера, друга його пароль:
~$ perl -MMIME::Base64 -e 'print encode_base64("sender\@server.com");'
c2VuZGVyQHNlcnZlci5jb20=
~$ perl -MMIME::Base64 -e 'print encode_base64("pa\$\$w0rd");'
cGEkJHcwcmQ=

Після цього можна спробувати поспілкуватися з smtp-сервером і спробувати авторизуватися:
EHLO localhost
AUTH LOGIN
c2VuZGVyQHNlcnZlci5jb20=
cGEkJHcwcmQ=
MAIL FROM: <sender@server.com>
RCPT TO: <user1@server.com>
RCPT TO: <user2@server.com>
DATA
From: Sender <sender@server.com>
To: Receiver1 <user1@server.com>
To: Receiver2 <user2@server.com>
Subject: Test SMTP
Content-Type: text/plain

Hi!
Test Auth.

.
QUIT

Замість AUTH LOGIN до речі можна використовувати й AUTH PLAIN чи, наприклад, AUTH CRAM-MD5, якщо це підтримується сервером і якщо знаєте як цим користуватися.

Варто також зауважити, що у наведених прикладах localhost варто замінити на реальне ім'я своєї системи, а у полях from та to вказувати реальних користувачів, інакше сервер легко може сприйняти вас за спамера і, відповідно, заблокувати відправлення пошти.