2016-10-28

Как сменить заголовок (dash) стрима на сервисе restream.io с помощью скрипта.

Сервис restream.io позволяет не только разливать стримы на несколько стрим-сервисов, но и централизованно управлять заголовками (дашами, по терминологии твича) на таких сервисах как Twitch или Youtube.

К сожалению разработчики не предоставили никакого апи для этого, так что пришлось заколхозить скрипт, который логинится на сайт и имитирует ручной ввод. Опять таки к сожалению форма ввода даша выполнена на JS, что усложнило заскриптовывание. К счастью, при помощи хромиума и модуля selenium для питона удалось написать скрипт, который делает все что нужно, при том - на безиксовом сервере.

Актуальная версия тут: https://github.com/qiwichupa/restream.io_title_change

2016-10-25

Очистка временных папок во всех профилях терминального сервера

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


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
Get-ChildItem -Path 'C:\Documents and Settings'   -Force `
    | foreach { $profilePath = $_.Fullname
                $path = $profilePath + "\\Local Settings\\Temp\\"
                Get-ChildItem -Path $path -Force | foreach {$_.FullName
                                                            Remove-Item $_.FullName -Recurse -Force 
                                                            }
                $path = $profilePath + "\\Local Settings\\Temporary Internet Files\\"
                Get-ChildItem -Path $path -Force | foreach {$_.FullName
                                                            Remove-Item $_.FullName -Recurse -Force 
                                                            }                                            
               }
              

2016-09-12

Proxmox и SMB/CIFS-хранилище


Использую Proxmox дома и столкнулся с неприятной проблемой - при бэкапе относительно больших (несколько гиг) виртуалок на сетевую хранилку (бомжовый QNAP), подключенную по NFS, Proxmox затыкался и повисал вхлам. Вероятно в этом виновата хранилка, возможно, не очень тянущая NFS, может быть в проксмоксе с этим какие-то проблемы, но я решил что пусть оно работает через самбу. Делать перманентное подключение не хотелось, так что я воспользовался autofs, которая неплохо зарекомендовала себя на моем ноуте.

Итак, ставим autofs на сервер проксмокса
aptitude install autofs

Создаем корневую папку для шар
mkdir /mnt/autofs

Редактируем /etc/auto.master, добавляя строку
/mnt/autofs /etc/auto.smb --timeout=300

Рестартим сервис
/etc/init.d/autofs restart

Тут надо сказать что это очень упрощенный подход без использования логина и пароля (моя шара домашняя и открыта для всех), и без указания конкретной шары. После всего проделанного, через корень /mnt/autofs будет доступно все сетевое окружение. Например мой NAS имеет IP 192.168.1.2 и шару Public, и я могу теперь обратиться к ней:
ls /mnt/autofs/192.168.1.2/Public

Далее все просто. Создаем папку для проксмокса
mkdir /mnt/autofs/192.168.1.2/Public/proxmox

Добавляем эту папку в стораджи как локальную директорию.



Такой метод вполне подходит для хранения бэкапов, темплейтов и исошников.

2016-09-08

Бэкап всех баз MySQL с ротацией (удалением старых) бэкапов

Скрипт делает дампы всех БД сервера, сохраняя в папки именованные по дате и времени создания. Сохраняются последние N (переменная $BACKUPS) бэкапов.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Optional variables for a backup script
MYSQL_USER="root"
MYSQL_PASS="password"
BACKUP_ROOT=/var/backups/mysql;
BACKUPS=2;
BACKUP_DIR="$BACKUP_ROOT/$(date +%Y-%m-%dT%H_%M_%S)";

# Create folders
test -d "$BACKUP_DIR" || mkdir -p "$BACKUP_DIR"
# Get the database list, exclude information_schema
for db in $(mysql -B -s -u $MYSQL_USER --password=$MYSQL_PASS -e 'show databases' | grep -v information_schema)
do
  # dump each database in a separate file
  mysqldump -u $MYSQL_USER --password=$MYSQL_PASS "$db" | gzip > "$BACKUP_DIR/$db.sql.gz"
done

# backup cleanup
ls "$BACKUP_ROOT" \
        | head -n$(expr $(ls "$BACKUP_ROOT" | wc -l) - $BACKUPS) \
        | while read in; 
                do rm -rf  "$BACKUP_ROOT/$in"; 
          done

2016-09-03

Aimp: database disk image is malformed

При возникновении такой ошибки стоит проверить файлы баз данных, которые использует AIMP. Они расположены в папке профиля: %appdata%\AIMP и немногочисленных подпапках.
Файлы баз имеют расширение *.db, проверить их можно утилитами для работы с sqlite, например: SqliteBrowser
Поврежденный файл можно просто удалить, если не удается его восстановить. При этом, конечно, в зависимости от файла может потеряться часть настроек - например обнулится медиатека.

2016-08-03

Поиск живых компьютеров в Active Directory

Скрипт для поиска компов, которые меняли свой внутренний пароль в AD в течение последних трех дней:

1
2
3
4
5
6
7
8
9
Import-Module ActiveDirectory

$lastCheckDays = 3

$filter =  (get-date).AddDays(-$lastCheckDays).ToString("dd/MM/yyyy")
get-adcomputer `
            -filter "Passwordlastset -gt '$filter'" `
            -properties * `
            | Select name,passwordlastset,OperatingSystem

Выполнять лучше на контроллере соответствующего домена

Если требуется собрать и свести в один файл информацию о комьютерах из разных доменов, можно использовать такой скрипт
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Import-Module ActiveDirectory

$tempfile   = 'c:\temp\comp.csv.temp'
$resultfile = 'c:\temp\comp.csv'
 

function DoDomain($dc)
    {
    $lastCheckDays = 30 # Максимум дней с обновления пароля
    $filter =  (get-date).AddDays(-$lastCheckDays).ToString("dd/MM/yyyy")

    $error.clear()
    try {Get-ADDomain -server "$dc" | Out-Null } # проверка доступности контроллера
    catch {"[Error] $dc" }
    if (!$error){ # если контроллер доступен - понеслась...
        # Вытаскиваем список живых компов, 
        # экспортируем во временный файл, вырезая заголовки
        get-adcomputer `
                    -filter "Passwordlastset -gt '$filter'" `
                    -server "$dc"`
                    -properties name,CanonicalName,passwordlastset,OperatingSystem `
                    | Select name,CanonicalName,passwordlastset,OperatingSystem  `
                    | ConvertTo-Csv -NoTypeInformation `
                    | Select-Object -Skip 1 `
                    | Out-File "$tempfile" 

        #импортируем временный файл с другими заголовками, 
        $tmp = Import-Csv -Header Name,Domain,Date,OS $tempfile

        # из поля с указанием домена и OU компьютера вырезаем все кроме домена
        # для удобства фильтрации по домену например в экселе
        $tmp | ForEach-Object {$_.Domain = [regex]::replace($_.Domain,'/.*','') }

        # выбираем добавлять ли заголовок во временный файл. 
        # Добавляем, если результирующий файл еще не был создан и, следовательно
        # это первый обработанный домен. Записываем временный файл
        if (Test-Path "$resultfile") {
            $tmp | ConvertTo-Csv -NoTypeInformation | Select-Object -Skip 1 | Out-File "$tempfile" 
            } else {
            $tmp | ConvertTo-Csv -NoTypeInformation |  Out-File "$tempfile" 
            }

        # Добавляем временный файл в конец результирующего
        [System.IO.File]::ReadAllText("$tempfile") | Out-File "$resultfile" -Append 
        
        # пробегаемся по результирующему файлу, удаляя пустые строки 
        # (опять же важно для экселя, чтобы первую строку сделать фильром)
        [System.IO.File]::ReadAllText("$resultfile")  -replace '\s+\r\n+', "`r`n" |  Out-File "$resultfile"
        Remove-Item "$tempfile"
        }
    }




Remove-Item "$resultfile" 

DoDomain("dc.domain1.local")
DoDomain("dc.domain2.local")
DoDomain("dc.domain3.local")

Важно! На контроллерах доменов должна работать служба Active Directory Web Services.
Для контроллеров на Windows 2003, если данная служба не установлена, потребуется установить NET Framework 3.5 SP1, а также патч на фреймворк KB969166 (у микрософта доступен только через общение с саппортом так что выкладываю архив), ну и саму службу

2016-05-21

proxmox: shrink lxc container

Proxmox 4.2
Container: 101
Storage: iSCSI with group "iscsi-lvm-group"
Current size: 20G
Needed size: 10G
  1. BACKUP FIRST!
  2. Stop VM
    lcx-stop -n 101
  3. Check disk
    e2fsck -f  /dev/iscsi-lvm-group/vm-101-disk-1
    (
    use tune2fs if "MMP check failed" error, and e2fsck again)
  4. Do your disk little smaller that you want
    resize2fs /dev/iscsi-lvm-group/vm-101-disk-1 9G
  5. Reduce LVM size to what you want
    lvreduce -L 10G /dev/iscsi-lvm-group/vm-101-disk-1
  6. Resize your disk without size parameter
    resize2fs /dev/iscsi-lvm-group/vm-101-disk-1
  7. Check disk
    e2fsck -f  /dev/iscsi-lvm-group/vm-101-disk-1
    (
    use tune2fs if "MMP check failed" error, and e2fsck again)
  8. Edit disk size in container config
    vi /etc/pve/lxc/101.conf
  9. Run the container

2016-05-12

Поиск левого DHCP для самых маленьких

Маленькая детективная история, которая началась с того, что у клиентов начали появляться трудности с доступом к сетевым ресурсам. Выяснилось что они получают IP-адреса с какого-от левого источника (да, это можно предотвратить, но что не сделано - то не сделано).

Что делаем:

  1. на компе, получившим левый адрес, делаем
    ipconfig /all

    смотрим IP DHCP-сервера: в моем случае 192.168.1.1, он же шлюз - типичная ситуация "кто-то умный принес домашний роутер".
    (Для полноты картины качаем Rogue Checker - утилиту для поиска DHCP-серверов в сети. Полезно для мониторинга ситуации со стороны)
  2. Имея комп с левый адресом пингуем IP DHCP-сервера
    ping 192.168.1.1
    и дальше
    arp -a
    последняя команда выдаст MAC-адрес DHCP-сервера
  3. ищем MAC-адрес на свичах, выясняем порт на котором висит "злоумышленник" (я для этого использую богоподобный скрипт port_report.py)
  4. Если порт подписан и понятно где находится розетка - идем и рассказываем человеку о безопасности на предприятии. Если розетка не подписана - смотрим какие мак-адреса висят на том же порту, если таковые есть - это скорее всего какое-то оборудование предприятия - компы, ip-телефоны и т.д., которые были воткнуты в принесенный роутер.
В моем случае человек принес роутер чтобы к одной розетке подключить несколько компов. При этом использовал его как хаб, таким образом клиентский порт роутера оказался соединен с нашей локалкой, что и вызвало проблемы. К счастью, по засветившимся на порту мак-адресам мы быстро установили какому оборудованию принадлежат маки (спасибо автоматической базе инвентаризации) и на ком это оборудование числится.


2016-05-07

Исправление крестовины (D-Pad) геймпада Retro-bit SNES Gamepad


Для удобства игры на старой Super Famicom прикупил себе пару беспроводных геймпадов Retro-bit (ebay). Нареканий в части беспроводной работы к ним не возникло, но выяснилось, что крестовина (aka directional pad, aka D-Pad) у них самая премерзкая - при нажатии одного из направлений практически неизбежно прожимается одно из смежных. К счастью это оказалось несложно исправить.


2016-04-07

Как убить лишние копии процесса в windows

Потребовалось сотворить костыль, убивающий незавершающиеся копии процесса, на всякий случай оставив последние из запущенных. В моем случае это костыль, но в целом кому-то может и пригодиться, так что выкладываю рецепт на powershell:

$processName = "php-cgi"
$survivorsCount = 6

$processList = Get-Process -Name $processName
$doomedCount = $processList.Count

if ($doomedCount  -gt $survivorsCount) {
  $bulletCount = $doomedCount - $survivorsCount
  $bulletCount
  $killkillkill = $processList | Select-Object -first $bulletCount | Stop-Process -force
}
Сгенерировано: hilite.me

2016-04-01

Простейший пингер с логированием под bash

Собственно пингуем, ведем лог и это все что надо )

#!/bin/bash

if [[ -z "$1" ]]; then
    echo "Please enter IP, ex.: $0 127.0.0.1"
    exit
else
    echo "Logfile: /tmp/ping_$1"
fi

while true
do
    
    while ! ping -c1 $1 &>/dev/null
 do echo "Ping Fail - `date`" >> /tmp/ping_$1
    done

    echo "Host Found - `date`" >> /tmp/ping_$1
    sleep 1
done

2016-03-08

Как по порядку переименовать файлы, скачанные wget по списку

Решил скачать комикс из вконтакта, полученный список (listfile.txt) для скачивания имел примерно такой вид:

https://pp.vk.me/c307313/v307313650/1e94/bj560KCwYY4.jpg
https://pp.vk.me/c307313/v307313650/1692/yFPMOuXHLvw.jpg
...
https://pp.vk.me/c307313/v307313650/1e7b/d-MXTKSZr34.jpg
https://pp.vk.me/c307313/v307313650/1e84/Oj_DhH9Fbvw.jpg

Собственно, после скачивания wget'ом (wget -i listfile.txt) я получил неудобоваримый набор файлов с рандомными названиями, и мне захотелось переименовать их в вид 001.jpg 002.jpg, согласно порядку, в котором они были в исходном файле. Хорошенько попотев, получил такой однострочник:

cat ./listfile.txt | tr -d  '\r' |  while read url; do n=$((n+1)); file="`echo $url| sed -e 's/.*\///'`"; newfile="`printf \"%03d\" $n`";  mv  ./"$file"  ./"$newfile".jpg ;  done


Или, для читаемости, так:

cat ./listfile.txt | tr -d  '\r' |  while read url; 
do 
    n=$((n+1)); 
    file="`echo $url| sed -e 's/.*\///'`"; 
    newfile="`printf \"%03d\" $n`";  
    mv  ./"$file"  ./"$newfile".jpg ;  
done

Немного пояснений:

tr -d  '\r'  - исходный файл у меня был виндовосформирован, поэтому в каждой строке там был лишний символ перевода коретки, который мешался

while read url - стандартный цикл построчного чтения файла в переменную url

n=$((n+1)) - переменная n для нового имени файлов, которая будет прирастать на единицу

file="`echo $url| sed -e 's/.*\///'`" - старое имя файла, которое получается путем обрезания левой части ссылки

newfile="`printf \"%03d\" $n`" - новое имя файла, которое состоит из переменной n сформатированной в трехсимвольное отображение (1,2,3 -> 001, 002, 003).

2016-02-15

Не подключаются мобильные устройства по MTP

Если после установки антивируса касперского к компьютеру перестали подключаться смартфоны, стоит проверить ветку реестра:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{EEC5AD98-8080-425F-922A-DABF3DE3F69A}

Если в ней есть ключи UpperFilters или LowerFilters - удалите их. Массово это можно сделать, проимпортировав политиками reg-файл:

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{EEC5AD98-8080-425F-922A-DABF3DE3F69A}]
"UpperFilters"=-
"LowerFilters"=-


Также в интернете встречаются упоминания о ветках:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{36FC9E60-C465-11CF-8056-444553540000} - наличие фильтров тут может привести к неработоспособности всех юсб-устройств,


HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E965-E325-11CE-BFC1-08002BE10318} - ветка, отвечающая за CD-ROM'ы


2016-01-20

Яндекс.Сервер 2010.09: Руководство по установке и эксплуатации

Удивительно, но в инете решительно не гуглится этот документ: yandex-server-manual.pdf
(скачать Яндекс.Сервер 2010.09 win+lin можно по ссылке)

2016-01-14

Логирование изменений конфигурации Cisco Catalyst на syslog

via @ https://networklessons.com/network-management/configuration-change-notification-logging/
! Находясь в режиме конфигурации
Router(config)#archive
Router(config-archive)#log config
! Включаем логирование
Router(config-archive-log-cfg)#logging enable
! Устанавливаем размер локального лога
Router(config-archive-log-cfg)#logging size 500
! Запрещаем сохранять пароли
Router(config-archive-log-cfg)#hidekeys
! Включаем перенаправление на сислог
Router(config-archive-log-cfg)#notify syslog
! Просматриваем локальный лог
Router#show archive log config all