Самоподписной сертификат gost2012

Чтобы не забыть. Собрал под Centos 7 openssl1.1 и отдельно к нему дивижок gost из этой репки

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

$ openssl req   -engine gost   \
-newkey gost2012_512    \
-pkeyopt paramset:A     \
-passout pass:1234567890  \
   -subj "/C=RU/ST=Moscow/L=Moscow/O=foo_bar/OU=foo_bar
/CN=developer/[email protected]" \
   -keyout private-test.key  \
   -out certificate-test.csr -md_gost12_512

Доступные алгоритмы можно найти тут.
Доступные методы хеширования получить так:

$ openssl
OpenSSL> engine gost
OpenSSL> list -digest-algorithms

Генерируем сам сертификат:

$ openssl x509 -req -days 365 \
-in certificate-test.csr \
-signkey private-test.key \
-out certificate-test.pem \
-engine gost

Посмотреть что вышло можно так:

$ openssl x509 -engine gost -in certificate-test.pem  -text --noout 
Certificate:
   Data:
       Version: 1 (0x0)
       Serial Number:
           2f:54:7c:f3:05:1a:27:4e:e0:db:c3:03:09:81:7c:ef:da:39:d1:cc
       Signature Algorithm: GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)
       Issuer: C = RU, ST = Moscow, L = Moscow, O = foo_bar, OU = foo_bar, CN = developer, emailAddress = [email protected]
       Validity
           Not Before: Feb 13 16:07:23 2019 GMT
           Not After : Feb 13 16:07:23 2020 GMT
       Subject: C = RU, ST = Moscow, L = Moscow, O = foo_bar, OU = foo_bar, CN = developer, emailAddress = [email protected]
       Subject Public Key Info:
           Public Key Algorithm: GOST R 34.10-2012 with 512 bit modulus
               Public key:
                  X:5E6286D582F33981E60FCF0C932B07A12726E3962F127C161A2BD569A404BC41881922F3F8B6FD402FE1BA093FD04F9AF489EE0637ED18D58FCC8724747494A4
                  Y:9455534A534C4D407C1F134F72FAB196D1110E48042260B84E5B4F1A3D255E688AA5C57580D6718C1713584869316F7D452ABC698FBAF3D5AF0BB6BEF1F8D3F8
               Parameter set: GOST R 34.10-2012 (512 bit) ParamSet A
   Signature Algorithm: GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)
        28:2b:ed:a5:39:2d:41:47:47:eb:03:55:ca:e1:89:6f:35:12:
        7d:6d:ba:27:cf:30:f5:c0:37:8b:dd:c7:a2:52:16:7c:ee:cb:
        29:f6:0b:00:6a:1b:02:cd:29:60:32:b8:bc:35:a0:93:46:fa:
        b2:25:bc:b7:06:d4:34:dc:a6:65:c8:66:ce:c8:d5:02:5d:fb:
        77:0e:d1:c0:73:f9:af:87:72:89:c3:bd:df:33:ac:ca:74:a6:
        33:aa:01:53:89:09:e6:7e:57:49:b1:7b:36:86:a6:04:ec:d4:
        49:1a:27:98:5e:e1:36:a5:74:5a:54:b0:5a:23:83:c9:be:b3:
        6c:4c

  

Шпаргалка rpm

Просмотр встроенных макросов (можно фильтровать с помощью grep):
rpm --showrc

Просмотр результатов раскрытия конкретных макросов:

rpm --eval "%systemd_post daemond.service",
rpm --eval %_libdir

Объявит макрос в спеке в текущей секции:
%define _some_dir /opt/some/path

Объявит макрос во всей спеке (нужно объявлять в первых строках спекфайла):

%global _some_dir /opt/some/path

Общий синтаксис объявления макроса

%global <macro_name_here> <macro_default_value>
%define <macro_name_here> <macro_default_value>

Значения макроса прокидывается с помощью параметра
--define "<macro_name_here><macro_value>"

Смотрим как раскроются макросы во всей спеке:

rpmspec \
--define "macro_name macro_value" \
--parse some-spec-file.spec

Отключит debuginfo пакет
%global debug_package %{nil}

Соберет только бинарный rpm:
rpmbuild -bb some-spec.spec

Соберет пакет с исходниками:
rpmbuild -bs some-spec.spec

Соберет бинарный пакет и пакет с исходниками:

rpmbuild -ba some-spec.spec

Собрать SRPM под el5 из под el7
rpmbuild -bs --define "_sourcedir $PWD" --target x86_64-linux-el5 --define "_source_filedigest_algorithm md5" --define "dist .el5" specfile.spec

PostgreSQL и некоторые запросы

структура базы

Этот пост я пишу как частичную текстовую расшифровку видео с 1:14:42. Не знаю как Вам, но я не особо люблю смотреть видюшки, и легче воспринимаю написанное текстом с примерами. Поэтому делаю заметку для себя, но если оно окажется еще кому-то полезным — буду рад.

Создадим таблички вот такой структуры как на картинке и заполним их данными:

-- Таблица с постами
CREATE TABLE post(
			id bigserial PRIMARY KEY,
			person_id int8 NOT NULL,
			created_at timestamptz NOT NULL,
			something text
		);
-- Добавляем миллион записей с данными
INSERT INTO
		post(
			person_id,
			created_at,
			something
		) SELECT
			(random()* 10 ^5)::int8 AS person_id,
			now()- INTERVAL '1 minute' *(random()* 60 * 24 * 365 * 2) AS created_at,
			(
				SELECT
					string_agg( substr( 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW XYZ0123456789 ',( random()* 72 )::INTEGER + 1, 1 ), '' )
				FROM
					generate_series(
						1,
						100 + i % 10 +(random()* 2000)::INTEGER
					)
			) AS something FROM generate_series(1, 1000000) AS g(i);
 
-- Удаляем записи записи одного автора у которых совпадает время
DELETE FROM post
WHERE
	(
		person_id,
		created_at
	) IN(
		SELECT
			person_id,
			created_at
		FROM
			post
		GROUP BY
			person_id,
			created_at
		HAVING
			COUNT(*) &gt; 1
	);
 
-- Индекс по времени
CREATE
	INDEX i_post_created_at ON
	post
		USING btree(created_at);
 
-- Уникальный индекс по дате и автору
CREATE
	UNIQUE INDEX u_post_author_id_created_at ON
	post(
		person_id,
		created_at
	);
 
-- Табличка с авторами
CREATE
	TABLE
		person AS SELECT
			DISTINCT ON
			(person_id) person_id AS id,
			'person_' || person_id AS name
		FROM
			post;
 
-- Первичный ключ
ALTER TABLE
	person ADD PRIMARY KEY(id);
 
-- Внешний ключ. Не верьте тем, кто говорят что не нужно их использовать. С ними гораздо лучше.
ALTER TABLE
	post ADD CONSTRAINT fk_post_person_id FOREIGN KEY(person_id) REFERENCES person(id);
-- Собираем статистику
analyze post;
analyze person;

Далее пишем запросы которые выбирают какие-то данные из этих таблиц.
Первое и самое простое — посчитать количество постов, которое у нас есть в post

SELECT COUNT(*) FROM post;
COUNT  
---------
 1000000
(1 строка)

Этот запрос выполняется по следующему плану:

explain analyse select count(*) from post;
                                                      QUERY PLAN                                                      
----------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=142283.69..142283.70 rows=1 width=8) (actual time=388.014..388.014 rows=1 loops=1)
   ->  Seq Scan on post  (cost=0.00..139784.35 rows=999735 width=0) (actual time=0.032..327.397 rows=1000000 loops=1)
 Planning time: 0.241 ms
 Execution time: 388.114 ms
(4 строки)

Видим сколько оно выполнялось. Это долго, если учесть что мы просто прочитали миллион строк и подсчитали их количество.

Самый быстрый и простой способ посмотреть сколько строчек в таблице — это заглянуть в статистику. Число будет не точным, но если у нас автовакуум настроен агрессивно и делает свою работу вовремя, то на полученное число можно ориентироваться:

explain select count(*) from post;
                             QUERY PLAN                             
--------------------------------------------------------------------
 Aggregate  (cost=142281.59..142281.60 rows=1 width=8)
   ->  Seq Scan on post  (cost=0.00..139782.67 rows=999567 width=0)
(2 строки)

Мы только что запускали analyze post; так что значение 999567 очень близко к точному значению.

В ситуации когда нам необходимо количество постов одного конкретного автора мы можем заставить его делать Index Only Scan и это будет очень быстро

explain analyze SELECT count(person_id) from post where person_id=1;
                                                                   QUERY PLAN                                                                   
------------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=48.64..48.65 rows=1 width=8) (actual time=0.143..0.144 rows=1 loops=1)
   ->  Index Only Scan using u_post_author_id_created_at on post  (cost=0.42..48.61 rows=11 width=8) (actual time=0.060..0.115 rows=14 loops=1)
         Index Cond: (person_id = 1)
         Heap Fetches: 14
 Planning time: 0.395 ms
 Execution time: 0.277 ms
(6 строк)

Здесь мы в качестве параметра count() подставляем то же индексированное поле, по которому ограничиваем выборку в выражении where, таким образом, из индекса мы получаем все необходимое для формирования результата и postgres даже не обращается к страницам самой таблицы. Тут важную роль играет селективность person_id. Если бы выборка получалась больше некоторого значения, то, возможно, было бы дешевле сделать Bitmap Index Scan. В любом случае актуальность статистики и карты видимости очень важны для правильной оценки оптимального плана.
Больше про count() можно почитать в статье Joe Nelson Faster PostgreSQL Counting или тут

В следующем посте поговорим о пагинации и почему offset плохо.

Обновление Samba 4.5.3 с поддержкой AD

Обновил samba до версии 4.5.3. Дело в том, что я раньше собирал этот пакет как samba4, но вышло обновление в Centos 7 где samba4 заобсолетили и обновили до 4.4.x причем собрана она у них без поддержки AD. Такое обновление мне все сломало, пришлось спешно обновляться с 4.2 до 4.5. благо все прошло без особых проблем. Только клиенты на база Windows XP SP3 перестали авторизовываться, но это вылечилось добавлением в конфиг одной строчки:

[global]

ntlm auth = yes

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

# samba-tool dbcheck

ext4 file-based шифрование

Начиная с ядра 4.1 добавлена опция CONFIG_EXT4_ENCRYPTION. Эта штука включает реализацию шифрования в драйвере ext4. С его помощью можно шифровать отдельные части файловой системы, например отдельно взятую директорию.
Так вышло что я использую на десктопе ROSA Fresh, однако последний релиз этой системы хоть и имеет версию ядра выше 4.1 а вот инструментарий для такого функционала отсутствует. Необходимые утилиты появились лишь в e2fsprogs-1.43. Но не беда. На ABF я нашел свежую сборку R9 (это пока даже не альфа) и там как раз ядро v4.8.7 и e2fsprogs-1.43.3, т.е. все необходимое уже есть. Качаем, ставим в виртуалку и пробуем.
Я ставил опыты на файлововой системе, смонтированной в /home, устройство /dev/sda6.
1. Сначала включим функционал (не включайте это на загрузочном разделе. GRUB это не поймет и не сможет загрузить систему)

sudo tune2fs -O encrypt /dev/sda6

2. Теперь создадим файлик с солью:

echo 0x$(head -c 16 /dev/urandom | xxd -p)>~/.cryptoSalt

3. Создадим директорию которую будем шифровать:

mkdir ~/crypted

4. Ну и применим к ней шифрование, ключ набиваем с клавиатуры:

/usr/sbin/e4crypt add_key -S `cat ~/.cryptoSalt` ~/crypted

Теперь в директории ~/crypted можно создавать папочки и файлики как обычно.
После перезагрузки Вы не сможете прочитать содержимое. Точнее сможете видеть, что там есть файлы и директории, но их имена будут искажены, а содержимое файлов и вовсе не читается. Чтобы снова видеть все в нормальном виде, нужно снова выполнить

/usr/sbin/e4crypt add_key -S `cat ~/.cryptoSalt` ~/crypted

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

Обновление PostgreSQL 9.6, 9.5 для 1C

Собрал обновления PostgreSQL 9.6.1, 9.5.5 для 1C. Для 9.4 больше собирать не буду, потому как сам их не использую. Если кому нужно — пишите.
Все сборки делаю только под Linux RH-based 6.x и 7.x, x86 и x86_64.
Ссылки на репозитории:
6.x x86_64
6.x x86
7.x x86_64
7.x x86

1C и временные файлы

diskio
Вот так меняется нагрузка на диск, если на сервере с Centos 7 на котором работает 1C и PostgreSQL выполнить:

systemctl enable tmp.mount

и перезагрузить. А все потому, что рабочий процесс 1С активно что то пишет в /tmp периодически создавая и удаляя файлы вида /tmp/v8*

# ls -la /tmp/v8*
-rw-r----- 1 usr1cv8 grp1cv8    0 окт 25 09:25 /tmp/v8l8JHMkf
-rw-r----- 1 usr1cv8 grp1cv8    0 окт 25 09:23 /tmp/v8lEjNyic
-rw-r----- 1 usr1cv8 grp1cv8    0 окт 25 09:03 /tmp/v8lP1GUax
-rw-r----- 1 usr1cv8 grp1cv8    0 окт 25 09:25 /tmp/v8lSHrEO6
-rw-r----- 1 usr1cv8 grp1cv8 1019 окт 25 08:58 /tmp/v8_P1GUax_1.tmp
-rw-r----- 1 usr1cv8 grp1cv8 3621 окт 25 08:58 /tmp/v8_P1GUax_2.tmp
-rw-r----- 1 usr1cv8 grp1cv8 6385 окт 25 08:58 /tmp/v8_P1GUax_3.tmp

PostgreSQL 9.6.0 & 1C

Буквально вчера вышел Postgres 9.6, я сегодня я уже тестирую его в связке с 1C.
Пакеты собрал для Centos6 и Centos7. Патч модифицировал сам и чисто механически, т.к. не являюсь программистом.
В принципе у 1C ни каких претензий не обнаружилось пока. Вроде работает, но по боевому я пока не рискую это ставить.

Asterisk в RPM репозитории

asteriskВстала задачка развернуть SIP-сервер для нужд маленького офиса. Гуглегие показало большое количество HOWTO по сборке Asterisk из исходников, да еще и для RH 6.x. Мне такой подход к развертыванию сервисов решительно не нравится, по этому решил я сделать репозиторий с пакетами да еще и под 7.x
Итак, устанавливаем, например Centos 7.2 в минимальной конфигурации и подключаем репозиторий:

cat &lt;&lt; EOF &gt; /etc/yum.repos.d/asterisk.repo
[Asterisk]
name=Asterisk-\$releasever
baseurl=http://abf-downloads.rosalinux.ru/asterisk_personal/repository/rosa-server72/\$basearch/main/release/
gpgcheck=0
enabled=1
EOF

И устанавливаем вполне себе штатно:

# yum install asterisk asterisk-configs

В качестве бонуса, так же в пакеты, я собрал русскую озвучку:

asterisk-sounds-core-ru-alaw.noarch : Asterisk core sounds - ru - alaw.
asterisk-sounds-core-ru-g722.noarch : Asterisk core sounds - ru - g722.
asterisk-sounds-core-ru-gsm.noarch : Asterisk core sounds - ru - gsm.
asterisk-sounds-core-ru-ulaw.noarch : Asterisk core sounds - ru - ulaw.

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