butenin.ru

... non penis canina est!

Пользовательские параметры Zabbix Agent в Windows и кодировка

Предположим, на каком-то сервере с Windows у нас установлен Zabbix Agent, при этом настроен такой пользовательский параметр:

1
UserParameter=UserParameter,C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -NonInteractive -File "C:\Scripts\script.ps1"

Скрипт script.ps1 отдаёт строковое значение, да ещё и на русском:

script.ps1
1
Write-Host "Значение пользовательского параметра"

Если попробовать получить значение параметра с сервера, возникает проблема:

1
2
$ zabbix_get -s example.com -k UserParameter
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

Причина в том, что наш скрипт на PowerShell выдаёт значение в кодировке консоли – CP866, а нужно – в UTF8. Меняем скрипт:

script.ps1
1
2
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::WriteLine("Значение пользовательского параметра")

Проверяем:

1
2
$ zabbix_get -s example.com -k UserParameter
Значение пользовательского параметра

Свой KMS-сервер

Требования: питон 2.6 или 2.7, python-argparse (в 2.7 идёт в комплекте), python-tz (для локального времени в выводе скрипта).

Первым делом идём сюда, далее по ссылкам. Скачиваем py-kms_2014-01-03T032458Z.zip или более поздний вариант. Кладём его на сервер, распаковываем в /usr/local/pykms.

В файле server.py в самом начале добавляем shebang:

server.py
1
#!/usr/bin/python

Создаём init-скрипт и сохраняем его как /etc/init.d/pykms:

/etc/init.d/pykms
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
#!/bin/sh

### BEGIN INIT INFO
# Provides:          myservice
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Put a short description of the service here
# Description:       Put a long description of the service here
### END INIT INFO

DIR=/usr/local/pykms
DAEMON=$DIR/server.py
DAEMON_NAME=PyKMS

DAEMON_USER=root

PIDFILE=/var/run/$DAEMON_NAME.pid

. /lib/lsb/init-functions

do_start () {
  log_daemon_msg "Starting system $DAEMON_NAME daemon"
  start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --user $DAEMON_USER --chuid $DAEMON_USER --startas $DAEMON
  log_end_msg $?
}

do_stop () {
  log_daemon_msg "Stopping system $DAEMON_NAME daemon"
  start-stop-daemon --stop --pidfile $PIDFILE --retry 10
  log_end_msg $?
}

case "$1" in

  start|stop)
      do_${1}
      ;;

  restart|reload|force-reload)
      do_stop
      do_start
      ;;

  status)
      status_of_proc "$DAEMON_NAME" "$DAEMON" && exit 0 || exit $?
  ;;

  *)
      echo "Usage: /etc/init.d/$DAEMON_NAME {start|stop|restart|status}"
      exit 1
  ;;
esac

exit 0

Делаем эти файлы исполняемыми и добавляем к уровням запуска по умолчанию:

1
2
3
chmod +x /usr/local/pykms/server.py
chmod +x /etc/init.d/pykms
update-rc.d pykms defaults

P.S. PyKMS на данный момент не умеет писать логи, работа с SQLite тоже под вопросом.

Разные полезности для Oracle

Размер схем:

1
2
set pagesize 50000
select owner, sum(bytes) / 1024 / 1024 / 1024 tsize from dba_segments group by owner order by tsize desc;

Текущие коннекты:

1
echo 'SELECT username FROM v$session WHERE username IS NOT NULL ORDER BY username ASC;' | sqlplus SYS/oracle as SYSDBA

Извращения с подключением:

1
expdp \"SYS/oracle@host/orcl as SYSDBA\" directory=DUMPS dumpfile=FULL.DMP FULL=Y

Создание пользователя Oracle

Поменять NEW_USER_NAME и NEW_USER_PASSWORD.

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
-- DROP USER NEW_USER_NAME CASCADE;

CREATE USER NEW_USER_NAME IDENTIFIED BY "NEW_USER_PASSWORD"
 DEFAULT TABLESPACE "USERS"
 TEMPORARY TABLESPACE "TEMP"
 QUOTA UNLIMITED ON "USERS";

GRANT ALTER ANY PROCEDURE TO NEW_USER_NAME;
GRANT ALTER ANY TABLE TO NEW_USER_NAME;
GRANT ALTER ANY TRIGGER TO NEW_USER_NAME;
GRANT ALTER PROFILE TO NEW_USER_NAME;
GRANT CREATE PROCEDURE TO NEW_USER_NAME;
GRANT CREATE SEQUENCE TO NEW_USER_NAME;
GRANT CREATE SESSION TO NEW_USER_NAME;
GRANT CREATE TABLE TO NEW_USER_NAME;
GRANT CREATE TRIGGER TO NEW_USER_NAME;
GRANT CREATE VIEW TO NEW_USER_NAME;
GRANT DELETE ANY TABLE TO NEW_USER_NAME;
GRANT DROP ANY PROCEDURE TO NEW_USER_NAME;
GRANT DROP ANY TABLE TO NEW_USER_NAME;
GRANT DROP ANY TRIGGER TO NEW_USER_NAME;
GRANT DROP ANY VIEW TO NEW_USER_NAME;
GRANT DROP PROFILE TO NEW_USER_NAME;

GRANT "CONNECT" TO NEW_USER_NAME;
ALTER USER NEW_USER_NAME DEFAULT ROLE ALL;

Установка Oracle Database 11gR2 на CentOS 6.5

Задача – установить Oracle Database 11gR2 на CentOS 6.5. Система при этом установлена в минимальной конфигурации из образа CentOS-6.5-x86_64-minimal.iso without all bells and whistles. Графический интерфейс не используется.

Disclaimer: инструкция “для себя”, делалась на скорую руку, но общие принципы работают.

После установки и первоначальной настройки системы, добавляем репозиторий и ключ Oracle:

1
2
3
cd /etc/yum.repos.d
sudo wget --no-check-certificate https://public-yum.oracle.com/public-yum-ol6.repo
sudo wget --no-check-certificate https://public-yum.oracle.com/RPM-GPG-KEY-oracle-ol6 -O /etc/pki/rpm-gpg/RPM-GPG-KEY-oracle

Ключ --no-check-certificate используется из-за того, что wget у нас версии 1.12, а поддержка SNI появилась только в 1.14.

Устанавливаем мета-пакет oracle-rdbms-server-11gR2-preinstall, он произведёт часть подготовительных операций:

1
sudo yum install oracle-rdbms-server-11gR2-preinstall

Чтобы не иметь проблем с разрешением собственного адреса, добавляем имя хоста в /etc/hosts:

/etc/hosts
1
2
127.0.0.1   db-oracle localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         db-oracle localhost localhost.localdomain localhost6 localhost6.localdomain6

Устанавливаем пароль пользователя oracle:

1
sudo passwd oracle

Меняем лимиты и политику SELinux:

/etc/security/limits.d/90-nproc.conf
1
2
3
4
5
6
# Default limit for number of user's processes to prevent
# accidental fork bombs.
# See rhbz #432903 for reasoning.

*          soft    nproc     16384
root       soft    nproc     unlimited
/etc/selinux/config
1
SELINUX=permissive

И перезагружаемся.

Добавляем переменные окружения в профиль пользователя oracle:

/home/oracle/.bash_profile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Oracle Settings
export TMP=/tmp
export TMPDIR=$TMP

export ORACLE_HOSTNAME=db-oracle
export ORACLE_UNQNAME=orcl
export ORACLE_BASE=/var/lib/oracle
export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/dbhome_1
export ORACLE_SID=orcl
export PATH=$ORACLE_HOME/bin:$PATH

export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
export CLASSPATH=$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib

export TZ=UTC/GMT

Создаём директории, где у нас всё будет располагаться:

/home/oracle/.bash_profile
1
2
3
4
5
6
sudo mkdir -p /var/lib/oracle/product/11.2.0/dbhome_1
sudo chown -R oracle:oinstall /var/lib/oracle
sudo chmod -R 775 /var/lib/oracle
sudo mkdir -p /var/lib/oraInventory
sudo chown -R oracle:oinstall /var/lib/oraInventory
sudo chmod -R 775 /var/lib/oraInventory

Создаём файл ответов для инсталлятора:

/home/oracle/db.rsp
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
oracle.install.responseFileVersion=/oracle/install/rspfmt_dbinstall_response_schema_v11_2_0
oracle.install.option=INSTALL_DB_AND_CONFIG
ORACLE_HOSTNAME=db-oracle
UNIX_GROUP_NAME=oinstall
INVENTORY_LOCATION=/var/lib/oraInventory
SELECTED_LANGUAGES=en,ru
ORACLE_HOME=/var/lib/oracle/product/11.2.0/dbhome_1
ORACLE_BASE=/var/lib/oracle
oracle.install.db.InstallEdition=EE
oracle.install.db.isCustomInstall=false
oracle.install.db.customComponents=
oracle.install.db.DBA_GROUP=dba
oracle.install.db.OPER_GROUP=dba
oracle.install.db.CLUSTER_NODES=
oracle.install.db.config.starterdb.type=GENERAL_PURPOSE
oracle.install.db.config.starterdb.globalDBName=orcl
oracle.install.db.config.starterdb.SID=orcl
oracle.install.db.config.starterdb.characterSet=AL32UTF8
oracle.install.db.config.starterdb.memoryLimit=748
oracle.install.db.config.starterdb.memoryOption=true
oracle.install.db.config.starterdb.installExampleSchemas=true
oracle.install.db.config.starterdb.enableSecuritySettings=true
oracle.install.db.config.starterdb.password.ALL=
oracle.install.db.config.starterdb.password.SYS=
oracle.install.db.config.starterdb.password.SYSTEM=
oracle.install.db.config.starterdb.password.SYSMAN=
oracle.install.db.config.starterdb.password.DBSNMP=
oracle.install.db.config.starterdb.control=DB_CONTROL
oracle.install.db.config.starterdb.gridcontrol.gridControlServiceURL=
oracle.install.db.config.starterdb.dbcontrol.enableEmailNotification=false
oracle.install.db.config.starterdb.dbcontrol.emailAddress=
oracle.install.db.config.starterdb.dbcontrol.SMTPServer=
oracle.install.db.config.starterdb.automatedBackup.enable=false
oracle.install.db.config.starterdb.automatedBackup.osuid=
oracle.install.db.config.starterdb.automatedBackup.ospwd=
oracle.install.db.config.starterdb.storageType=FILE_SYSTEM_STORAGE
oracle.install.db.config.starterdb.fileSystemStorage.dataLocation=/var/lib/oracle/oradata
oracle.install.db.config.starterdb.fileSystemStorage.recoveryLocation=
oracle.install.db.config.asm.diskGroup=
oracle.install.db.config.asm.ASMSNMPPassword=
MYORACLESUPPORT_USERNAME=
MYORACLESUPPORT_PASSWORD=
SECURITY_UPDATES_VIA_MYORACLESUPPORT=false
DECLINE_SECURITY_UPDATES=true
PROXY_HOST=
PROXY_PORT=

Скачиваем дистрибутив в домашнюю директорию пользователя oracle. Распаковываем и запускаем установщик:

1
2
3
4
5
6
sudo su - oracle
unzip linux.x64_11gR2_database_1of2.zip
unzip linux.x64_11gR2_database_2of2.zip
rm linux.x64_11gR2_database_*
cd database/
./runInstaller -responseFile ~/db.rsp -silent -nowelcome -ignorePrereq

В самом конце установщик попросит выполнить пару скриптов от имени пользователя root. Выполняем.

1
2
/var/lib/oraInventory/orainstRoot.sh
/var/lib/oracle/product/11.2.0/dbhome_1/root.sh

Ну и для полноты картины – init-скрипт для автоматического запуска Oracle Database:

/etc/init.d/oracle
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
#!/bin/bash

# oracle: Start/Stop Oracle Database 11g R2
#
# chkconfig: 345 90 10
# description: The Oracle Database Server is an RDBMS created by Oracle Corporation
#
# processname: oracle

. /etc/rc.d/init.d/functions

LOCKFILE=/var/lock/subsys/oracle
ORACLE_USER=oracle

case "$1" in
  'start')
      if [ -f $LOCKFILE ]; then
          echo $0 already running.
          exit 1
      fi
      echo -n $"Starting Oracle Database:"
      su - $ORACLE_USER -c '$ORACLE_HOME/bin/lsnrctl start'
      su - $ORACLE_USER -c '$ORACLE_HOME/bin/dbstart $ORACLE_HOME'
      su - $ORACLE_USER -c '$ORACLE_HOME/bin/emctl start dbconsole'
      touch $LOCKFILE
  ;;
  'stop')
      if [ ! -f $LOCKFILE ]; then
          echo $0 already stopping.
          exit 1
      fi
      echo -n $"Stopping Oracle Database:"
      su - $ORACLE_USER -c '$ORACLE_HOME/bin/lsnrctl stop'
      su - $ORACLE_USER -c '$ORACLE_HOME/bin/dbshut $ORACLE_HOME'
      su - $ORACLE_USER -c '$ORACLE_HOME/bin/emctl stop dbconsole'
      rm -f $LOCKFILE
  ;;
  'restart')
      $0 stop
      $0 start
  ;;
  'status')
      if [ -f $LOCKFILE ]; then
          echo $0 started.
      else
          echo $0 stopped.
      fi
  ;;
  *)
      echo "Usage: $0 [start|stop|status]"
      exit 1
esac

exit 0
1
2
chkconfig --add oracle
chkconfig --list oracle

В файле /etc/oratab меняем последнюю строчку:

/etc/oratab
1
orcl:/var/lib/oracle/product/11.2.0/dbhome_1:Y

Не забываем разрешить 1158/tcp и 1521/tcp в правилах файерволла, если нужно.

URL rewrite в IIS 7

Задача — сделать перенаправление на адрес https://example.com/app/ со следующих адресов:

  • http://example.com/app
  • http://example.com
  • https://example.com

Стандартое перенаправление не устраивает — при попытке открыть http://example.com/bad_url попадаем на адрес https://example.com/app/bad_url вместо 404-й ошибки.

Решение — скачиваем и устанавливаем расширение для IIS – URL Rewrite. В корне сайта правим файл web.config.

web.config
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
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
      <rewrite>
          <rules>

              <rule name="redirect HTTP requests" stopProcessing="true">
                  <match url="(^$)|(^app$)|(^app\/)" />
                      <conditions>
                          <add input="{HTTPS}" pattern="off" />
                      </conditions>
                  <action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/app/{R:1}" />
              </rule>

              <rule name="redirect HTTPS requests" stopProcessing="true">
                  <match url="(^$)" />
                      <conditions>
                          <add input="{HTTPS}" pattern="on" />
                      </conditions>
                  <action type="Redirect" redirectType="Found" url="https://{HTTP_HOST}/app/" />
              </rule>

          </rules>
      </rewrite>
  </system.webServer>
</configuration>

Синхронизация дисков с помощью nnBackup

1
"C:\Program Files (x86)\nnBackup\nnbackup.exe" sync -i V:\ -o W:\ -s -da -e -sa -dx "System Volume Information,$RECYCLE.BIN"

Задача для планировщика Windows:

Синхронизация дисков.xml
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
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2014-01-07T05:01:35.3739623</Date>
    <Author>home\butenin</Author>
  </RegistrationInfo>
  <Triggers>
    <CalendarTrigger>
      <StartBoundary>2014-01-07T03:00:00</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByDay>
        <DaysInterval>1</DaysInterval>
      </ScheduleByDay>
    </CalendarTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>home\butenin</UserId>
      <LogonType>InteractiveToken</LogonType>
      <RunLevel>LeastPrivilege</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT4H</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>"C:\Program Files (x86)\nnBackup\nnbackup.exe"</Command>
      <Arguments>sync -i V:\ -o W:\ -s -da -e -sa -dx "System Volume Information,$RECYCLE.BIN"</Arguments>
      <WorkingDirectory>C:\Program Files (x86)\nnBackup</WorkingDirectory>
    </Exec>
  </Actions>
</Task>

MD5 и SHA1 в Windows

Оказывается, есть у Microsoft своя утилита для расчёта хэшей MD5 и SHA1 — FCIV (File Checksum Integrity Verifier).

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
//
// File Checksum Integrity Verifier version 2.05.
//

Usage:  fciv.exe [Commands] <Options>

Commands: ( Default -add )

        -add    <file | dir> : Compute hash and send to output (default screen).
                dir options:
                -r       : recursive.
                -type    : ex: -type *.exe.
                -exc file: list of directories that should not be computed.
                -wp      : Without full path name. ( Default store full path)
                -bp      : specify base path to remove from full path name

        -list            : List entries in the database.
        -v               : Verify hashes.
                         : Option: -bp basepath.

        -? -h -help      : Extended Help.

Options:
        -md5 | -sha1 | -both    : Specify hashtype, default md5.
        -xml db                 : Specify database format and name.

To display the MD5 hash of a file, type fciv.exe filename

Хэши хранит в XML, выглядит примерно так:

1
2
3
<?xml version="1.0" encoding="utf-8"?>
<FCIV>
  <FILE_ENTRY><name>fciv.exe</name><MD5>4sbVYr01NStzwAp0TpwHxg==</MD5></FILE_ENTRY></FCIV>

Хотя и 2004 года, но, вроде бы, работает. Брать тут.