Установка туннеля с ГИС ЖКХ под Linux

Задача установить защищенный туннель с ГИС ЖКХ под Astra Linux.

Решение:

Сначала скопируем с токена сертификат в формате pfx. Для этого можно воспользоваться утилитой P12FromGostCSP (Windows). Под Linux тоже как-то можно, но как- нужно гуглить. Мне предоставили уже готовый файл.

Далее нужно установить крипто-про CSP с пакетом stunnel. Зайдя в крипто про, во вкладке «сертификаты» необходимо установить корневые сертификаты с https://my.dom.gosuslugi.ru/ и установить сертификат из файла psk.

Для настройки конфигурационного файла stunnel, нужно из файла формата pfx получить файлы key и crt

crt и pem:

openssl pkcs12 -in file.pfx -clcerts -nokeys -out public.crt
openssl x509 -in public.crt -out public.pem -outform PEM

key:

openssl pkcs12 -in SSK_obezl_3.pfx -nocerts -out private.key

Лично у меня на этом месте выскочила ошибка:

Enter Import Password:
Error outputting keys and certificates
124867336299712:error:06074079:digital envelope routines:EVP_PBE_CipherInit:unknown pbe algorithm:../crypto/evp/evp_pbe.c:95:TYPE=1.2.840.113549.1.12.1.80
124867336299712:error:23077073:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 algor cipherinit error:../crypto/pkcs12/p12_decr.c:41:
124867336299712:error:2306A075:PKCS12 routines:PKCS12_item_decrypt_d2i:pkcs12 pbe crypt error:../crypto/pkcs12/p12_decr.c:94:

Которую я так и не победил, но тем не менее файл сформировался.

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

pid=/home/vasya/stunnel/stunnel_cli.pid
output=/home/vasya/stunnel/t.log
socket = l:TCP_NODELAY=1
socket = r:TCP_NODELAY=1
debug = 7
[https]
client = yes
accept=localhost:8080
connect = api.dom.gosuslugi.ru:443
cert=/home/vasya/stunnel/public.pem
CAFile=/home/vasya/stunnel/CA-PPAK_2023.pem
key=/home/vasya/stunnel/private.key
verify=0

Файл CA-PPAK_2023.pem взял из архива «ГИС ЖКХ_Интеграция v.14.8.0.2.zip» с документацией скачанного с сайта https://my.dom.gosuslugi.ru/

И пробуем запустить туннель:

opt/cprocsp/sbin/amd64/stunnel_thread /home/vasya/stunnel/stunnel_run.conf

Логи будут писаться в файл t.log. Если всё хорошо, и в логах ошибок нет, то можно попробовать выполнить в браузере запрос вида:

http://127.0.0.1:8080/ext-bus-debt-service/services/DebtAsync

От ГИС ЖКХ придет что-то вроде:

<env:Envelope xmlns:ns6="http://dom.gosuslugi.ru/schema/integration/individual-registry-base/" xmlns:ns5="http://dom.gosuslugi.ru/schema/integration/account-base/" xmlns:ns8="http://dom.gosuslugi.ru/schema/integration/metering-device-base/" xmlns:ns7="http://dom.gosuslugi.ru/schema/integration/nsi-base/" xmlns:ns13="http://dom.gosuslugi.ru/schema/integration/debts/" xmlns:ns9="http://dom.gosuslugi.ru/schema/integration/organizations-registry-base/" xmlns:ns12="http://dom.gosuslugi.ru/schema/integration/bills-base/" xmlns:ns11="http://dom.gosuslugi.ru/schema/integration/payments-base/" xmlns:ns10="http://dom.gosuslugi.ru/schema/integration/organizations-base/" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns4="http://dom.gosuslugi.ru/schema/integration/base/" xmlns:ns3="http://www.w3.org/2000/09/xmldsig#">
   <env:Body>
      <env:Fault>
         <faultcode>env:Server</faultcode>
         <faultstring>AUT011000: Нет активной ИС с данным сертификатом</faultstring>
         <detail>
            <ns4:Fault>
               <ns4:ErrorCode>AUT011000</ns4:ErrorCode>
               <ns4:ErrorMessage>Нет активной ИС с данным сертификатом</ns4:ErrorMessage>
            </ns4:Fault>
         </detail>
      </env:Fault>
   </env:Body>
</env:Envelope>

Тут всё просто — открываем заявку на сайте ГИС ЖКХ и добавляем сертификат.

P,S. Отладку запросов далее можно делать в утилите soapui, Как? Тема отдельной будущей статьи, когда буду разбираться с запросами

Автоматизация пережатия pdf файлов

Задача: есть некоя файловая помойка, размер которой вырос до неприличных размеров. Необходимо pdf файлы пережать до «еле читабельного» состояния.

Решение: напишем соответствующий скрипт на Bash

#! /bin/bash
from='2025-01-15'
to='2025-01-17'

find ~/wedwewe -type f -newermt "$from" ! -newermt "$to" -name "*.pdf" | while read fname; do
  echo "-compress: $fname"
  gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile=res.pdf "$fname"
  if [ $? -eq 0 ]; then
    echo OK
    mv res.pdf "$fname"
  else
    echo FAIL
  fi
done

Что делает этот скрипт? А просто ищет все файлы созданные в указанном диапазоне дат. Далее последовательно пытается пережать каждый файл, и если это происходит успешно, то заменяет оригинал на получившийся пережатый файл. Опции dPDFSETTINGS:

/screen Более низкое качество и меньший размер. (72 т/д)
/ebook Лучшее качество, но чуть больший размер (150 dpi)
/prepress Вывод имеет более высокий размер и качество (300 dpi)
/printer Качество вывода подходит для принтерной печати (300 dpi)
/default Выбирает вывод, который подходит для нескольких целей, однако может создавать большие PDF-файлы.

Update: со временем скрипт чуть изменился. А именно добавил проверку «а помогло ли сжатие». Если эффекта нет, то и не заменяем пережатый файл

#! /bin/bash
from='2025-01-13'
to='2025-01-17'

find ~/shwedwed -type f -newermt "$from" ! -newermt "$to" -name "*.pdf" | while read fname; do
  echo "-compress: $fname"
  gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray -dNOPAUSE -dQUIET -dBATCH -sOutputFile=res.pdf "$fname"
  if [ $? -eq 0 ]; then
    echo OK
    size_before=$(wc -c <"$fname")
    size_after=$(wc -c <"res.pdf")
    if [[ $size_before -gt $size_after ]]
	then 
	    echo "-результат сжатия хороший. Заменяем файл..."
	    mv res.pdf "$fname"
	else 
	    echo "-сжатие не удачное, пропускаем.."
    fi
  else
    echo FAIL
  fi
done

Печать на принтере TSC-210 из консоли

В ходе эксплуатации принтера этикеток TSC-210 в среде 1С под Linux выявилась особенность, что он не выдерживает правильные отступы при печати, даже при установке нужных параметров бумаги. Выходом явилось сохранение печати в файл, а затем печать полученного файла при помощи просто скрипта вида:

#!/usr/bin/sh
lpr -P цув-tsc210-03 -o portrait -o media=Custom.58x28mm -o page-top=5 -o page-bottom=1 -o page-left=1 -o page-right=1 -o page-border=none ~/Документы/вывод.ps

Яндекс OCR: разметка данных

В ходе использования облака Yandex OCR для распознавания данных, выявилось что при анализе получаемого на выходе JSON, очень не достаёт визуализации полученных данных. Для того чтобы эту ситуацию чуть улучшить, написал скриптик, который на входе получает картинку для распознавания и JSON полученный от Яндекса, а на выходе выдаёт картинку с нанесенными распознанными блоками и таблицами.

Собственно код:

<?php
$res=json_decode(file_get_contents("res.json"));  // прочитаем json
$source = imagecreatefromjpeg ("pdfs/11-1.jpg");
$pink = imagecolorallocate($source, 255, 105, 180);
$white = imagecolorallocate($source, 255, 255, 255);
$green = imagecolorallocate($source, 132, 135, 28);
$blue = imagecolorallocate($source, 0, 0, 255);

// размечаю блоки
$bl=0;
foreach ($res->result->textAnnotation->blocks as $block) {    
    $kof=1.5;
    $points=[];
    $points[]=$block->boundingBox->vertices[0]->x*$kof;
    $points[]=$block->boundingBox->vertices[0]->y*$kof;
    $points[]=$block->boundingBox->vertices[1]->x*$kof;
    $points[]=$block->boundingBox->vertices[1]->y*$kof;
    $points[]=$block->boundingBox->vertices[2]->x*$kof;
    $points[]=$block->boundingBox->vertices[2]->y*$kof;
    $points[]=$block->boundingBox->vertices[3]->x*$kof;
    $points[]=$block->boundingBox->vertices[3]->y*$kof;
    $points[]=$block->boundingBox->vertices[0]->x*$kof;
    $points[]=$block->boundingBox->vertices[0]->y*$kof;    
    imagepolygon($source,$points,$green);
    imagettftext($source,20,0,$points[0],$points[1],$green,"/usr/share/fonts/truetype/r7-office/ext/PTS55F.ttf",$bl);
    $bl++;
};

//размечаю таблицы
$bl=0;
foreach ($res->result->textAnnotation->tables as $table) {    
    $kof=2.1;
    $offset_x=110;
    $offset_y=10;
    $points=[];
    $points[]=$table->boundingBox->vertices[0]->x*$kof+$offset_x;
    $points[]=$table->boundingBox->vertices[0]->y*$kof+$offset_y;
    $points[]=$table->boundingBox->vertices[1]->x*$kof+$offset_x;
    $points[]=$table->boundingBox->vertices[1]->y*$kof+$offset_y;
    $points[]=$table->boundingBox->vertices[2]->x*$kof+$offset_x;
    $points[]=$table->boundingBox->vertices[2]->y*$kof+$offset_y;
    $points[]=$table->boundingBox->vertices[3]->x*$kof+$offset_x;
    $points[]=$table->boundingBox->vertices[3]->y*$kof+$offset_y;
    $points[]=$table->boundingBox->vertices[0]->x*$kof+$offset_x;
    $points[]=$table->boundingBox->vertices[0]->y*$kof+$offset_y;    
    imagepolygon($source,$points,$blue);
    imagettftext($source,20,0,$points[0],$points[1],$blue,"/usr/share/fonts/truetype/r7-office/ext/PTS55F.ttf",$bl);
    $bl++;
    
}
imagejpeg($source, 'out.jpg');

Получаем картинку вида:

разметка на основе Yandex.ocr

GitItea: does not appear to be a git repository

Как оказалось такая совершенно не очевидная ошибка показывается (помимо варианта что и на самом деле вы напутали с URL репозитария) и когда что-то случилось с вашим открытым SSH ключём. Соответственно достаточно сгенерировать новый:

ssh-keygen -t ed25519 -C "your_email@example.com"

А затем добавить содержимое файла ~/.ssh/id_ed25519.pub в админке GitItea в раздел «Ключи SSH»

1 3 4 5 6 7 60