Поиск по этому блогу

пятница, 1 декабря 2017 г.

Як перевірити з'єднання по https/http2?

Сподіваюся, що всім відомо, що звичайне з'єднання по http-протоколу можна перевірити використовуючи звичайну команду telnet:
$ telnet google.com.ua 80
Trying 172.217.20.163...
Connected to google.com.ua.
Escape character is '^]'.
GET /
HTTP/1.0 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Referrer-Policy: no-referrer
Location: http://www.google.com.ua/?gfe_rd=cr&dcr=0&ei=51chWtS7ErTi8Aed2bXIBA
Content-Length: 272
Date: Fri, 01 Dec 2017 13:23:51 GMT

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.com.ua/?gfe_rd=cr&dcr=0&ei=51chWtS7ErTi8Aed2bXIBA">here</A>.
</BODY></HTML>
Connection closed by foreign host.
А як перевірити https/http2?
Виявляється, що теж доволі просто:
$ openssl s_client -connect google.com.ua:443
CONNECTED(00000003)
depth=3 C = US, O = Equifax, OU = Equifax Secure Certificate Authority
verify return:1
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify return:1
depth=1 C = US, O = Google Inc, CN = Google Internet Authority G2
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google Inc, CN = google.com
verify return:1
---
Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=google.com
   i:/C=US/O=Google Inc/CN=Google Internet Authority G2
 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
   i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIgzjCCH7agAwIBAgIIC3opcadHGlowDQYJKoZIhvcNAQELBQAwSTELMAkGA1UE
…skip…
aVs=
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=google.com
issuer=/C=US/O=Google Inc/CN=Google Internet Authority G2
---
No client certificate CA names sent
---
SSL handshake has read 11078 bytes and written 415 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: CF87F01549DC0A0F009A3BE4125C7FC4CEA275ECA69BB770311C6D36FCF9D3F3
    Session-ID-ctx: 
    Master-Key: BFED552D2D80DDC539E59DAE4593F349FD4CB9AD334F3515640D213C3948771855C5F4EAA378025EF179BAD5FDC952AA
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 100800 (seconds)
    TLS session ticket:
    0000 - 00 f6 8f 2c 19 9c a3 e3-1b 90 16 f0 0d c3 f7 c2   ...,............
    …skip…
    00d0 - 13 56 e8 9f 2e                                    .V...

    Start Time: 1512134921
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
GET /
HTTP/1.0 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Referrer-Policy: no-referrer
Location: https://www.google.com.ua/?gfe_rd=cr&dcr=0&ei=DFkhWt_PNa_i8Aeci6y4AQ
Content-Length: 273
Date: Fri, 01 Dec 2017 13:28:44 GMT
Alt-Svc: hq=":443"; ma=2592000; quic=51303431; quic=51303339; quic=51303338; quic=51303337; quic=51303335,quic=":443"; ma=2592000; v="41,39,38,37,35"

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="https://www.google.com.ua/?gfe_rd=cr&dcr=0&ei=DFkhWt_PNa_i8Aeci6y4AQ">here</A>.
</BODY></HTML>
read:errno=0
От так от.

Приблизно те саме, але для smtp TLS:
openssl s_client -starttls smtp -crlf -connect smtp.mailgun.org:587
Ну, а по інших моментах певно man openssl допомогти зможе :)

среда, 21 июня 2017 г.

SSL Let's Encrypt

https://letsencrypt.org/getting-started/

Про проект Let's Encrypt - центр сертифікації, що надає безкоштовні криптографічні сертифікати X.509 для TLS шифрування (HTTPS). Процес видачі та подовження сертифікатів повністю автоматизовано. Сертифікати рівня «domain validation».

Все робиться через certbot, процес повністю автоматизовано.

Так як доступу до серверу pbx.ukrhub.net у нас немає (та він нам й не потрібний) то нехай відповідальний за цей сервер самостійно згенерує валідний сертифікат та налаштує cron для коректного його оновлення.

На прикладі для nginx.
$ sudo aptitude install certbot -t jessie-backports
$ sudo certbot certonly --webroot -w /var/www/olden.org.ua -d olden.org.ua
У конфігурації nginx. /etc/nginx/sites-enable/you.domain.name
ssl_certificate /etc/letsencrypt/live/you.domain.name/cert.pem;
ssl_certificate_key /etc/letsencrypt/live/olden.org.ua/privkey.pem;
Ну і десь у cron-і
$ sudo certbot renew

вторник, 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-сторінка за одну сесію не віддасть такий обсяг інформації. Ну, а кому треба то той перепідключиться до гостьового доступу. Принаймні більша частина сучасних пристроїв та операційних систем це робить автоматично.