Crimson.Lab

Лаборатория Кримсона

  • Регистриуем аккаунт на Amazon AWS

    Регистриуем аккаунт на Amazon AWS и создаём бесплатный vps на 1 год

    1. Первым делом находим сервис для приёма смс - @Sms_activ_2bot, (можно пополнить баланс через СБП), вводим название сервиса amazon, регион USA (~8 рублей за приём смс)
    2. Потом находим предоплаченную виртуальную карту на 2$ (можно на plati.market) или @WantToPayBot
    3. Регистриуемся на aws.amazon.com
    4. Ждём некоторое время пока завершится модерация
    5. Теперь создаём инстанс EC2 с образом Ubuntu в регионе us-east с обязательной пометкой Free Tier
    6. Открываем в Security group входящие порты для инстанса
      • Inbound rules->Edit inbound rules->Add rule
      • Type: All traffic
      • Source: 0.0.0.0/0
    7. Внимание! После перезагрузки инстанса будет присвоен новый IP адрес!
      1. Получаем бесплатный поддомен на freedns.afraid.org
      2. Устанавливаем dyndns-client клиент sudo apt install ddclient
      3. Вводим после установки, в консольном ui ddclient, логин/api ключ от freedns.afraid.org и домен который там получили.
      4. Проверяем настройки ddclient sudo nano /etc/ddclient.conf
      5. Перезагружаем инстанс, убеждаем что новый ip привязался к поддомену.

    p.s. Лимит трафика на месяц - 100 Gb, если больше - будут списания с привязанной карты.


  • Быстро сериализуем объект в json строку в IDEA

    Быстро сериализуем объект в json строку в IDEA

    Добавляем шаблон для быстрой генерации json из idea->toString без null значений Заходим в раздел toString() Generation Settings

    Alt+Ins->toString()->Settings->Templates toString() Generation Settings

    public java.lang.String toString() {
    StringJoiner s = new java.util.StringJoiner(",", "{", "}");
    #foreach ($member in $members)##
        #if(!$member.modifierStatic)##
    if ($member.name!=null) {##
    s.add("\"$member.name\":\""+##
            #if ($member.primitiveArray || $member.objectArray)##
    java.util.Arrays.toString($member.name)##
            #elseif ($member.string)##
                $member.accessor ##
            #else
                $member.accessor ##
            #end##
    +"\"");
    }
        #end
    #end
    return s.toString();
    }
    

  • Приручаем 6-в-1 кольцо Jakcom r5 smart ring

    Приручаем 6-в-1 кольцо Jakcom r5 smart ring

    Купить можно на aliexpress или на ozon, цены +- одинаковые (~2100 рублей)

    Читаем инструкцию, смотрим где располагаются метки

    • по бокам 2 метки t5577 (ID) 125 kHz
    • I и III это mifare1 (IC) 13.56 MHz
    • II и IV это ntag216 (nfc) 13.56 MHz

    Находим 2 пароля для ID меток

    1. 5469616e
    2. 51243648

    Выкидываем инструкцию, берём proxmark3/flipperzero и начинаем эксперименты! У Флиппера актуальная на текущий момент прошивка unleashed-070e

    Заходим в раздел 125kHz->Saved->Write and set pass, вводим один из паролей (5469616e или 51243648), пробуем записать метку.

    Для сброса пароля заходим в раздел 125kHz->Extra Actions->Clear T5577 Password

    НО! Если сбросить пароль на 2х метках сразу, то они будут синхронно перезаписываться, что слегка меня смутило, лучше оставить на одной из меток пароль.

    Теперь идём в proxmark3 изучать ID метки

    play

    Пробуем на боковых метках lf search

    [=] Note: False Positives ARE possible
    [=]
    [=] Checking for known tags...
    [=]
    [!] Specify one authentication mode
    [-] No known 125/134 kHz tags found!
    [=] Couldn't identify a chipset
    

    Уточняем метку lf t5 detect

    [!] Could not detect modulation automatically. Try setting it manually with 'lf t55xx config'
    

    Добавляем известный пароль из инструкции lf t5 detect -p 51243648

    [=]  Chip type......... T55x7
    [=]  Modulation........ ASK
    [=]  Bit rate.......... 5 - RF/64
    [=]  Inverted.......... No
    [=]  Offset............ 33
    [=]  Seq. terminator... Yes
    [=]  Block0............ 000880E0 (auto detect)
    [=]  Downlink mode..... default/fixed bit length
    [=]  Password set...... Yes
    [=]  Password.......... 51243648
    

    Дальше я попробовал сделать wipe… и всё пропало. Ни ответа, ни привета. Флиппер тоже молчит. Пробую выполнить запись напрямую (через тестовый режим)

    lf t55 write -b 0 -d 000880E0 -t
    lf t55 write -b 0 -d 000880E0 --r0 -t
    lf t55 write -b 0 -d 000880E0 --r1 -t
    lf t55 write -b 0 -d 000880E0 --r2 -t
    lf t55 write -b 0 -d 000880E0 --r3 -t
    

    Потом записываем любой id

    lf em 410x clone --id 0102030405
    

    И… тишина. Метка не читается.

    Пробую через флиппер Clear T5577 Password и метка оживает!

    Сразу пробую записать через флиппер ключи - всё записалось.

    Теперь очередь IC меток

    Флиппер прекрасно прочитал I и III метки, но не смог записать туда данные - data management is only possible with initial card Как magic эта метка не определяется, uid просто так не перебить. Значит будем записывать через proxmark3.

    Пробуем на метке I и III hf search

    [|] Searching for ISO14443-A tag...
    [+]  UID: AA BB CC DD
    [+] ATQA: 00 04
    [+]  SAK: 08 [2]
    [+] Possible types:
    [+]    MIFARE Classic 1K
    [=] proprietary non iso14443-4 card found, RATS not supported
    [+] Magic capabilities... Gen 2 / CUID
    [+] Magic capabilities... Gen 4 GDM / USCUID ( Magic Auth )
    [+] Prng detection....... weak
    [+] Valid ISO 14443-A tag found
    

    Дальше получаем дампы ключей hf mf autopwn, записываем новую метку hf mf restore –uid 11223344

    Проверяем на флиппере - Всё читается.

    NFC метки

    Это ntag216, можно записать визитку

    Габариты кольца

    Кольцо просто огромное (Размер L, самый большой) play


  • Альтернативный клиент для просмотра Reddit

    Альтернативный клиент для просмотра Reddit

    Летом 2023 года Reddit запретил ценовой политикой все альтернативные клиенты. Но использование api индивидуально для каждого клиента - бесплатно! На данный момент актуальный способ - Генератор apk Infinity for Reddit

    Следуем инструкции по созданию приложения

    1. Создаём API приложение на reddit и получаем api_token
      name: {ВашеИмяНаРеддит}s-app (Заменить {ВашеИмяНаРеддит} на ваше имя пользователя)
      Тип: Installed app
      redirect uri: http://127.0.0.1
      
    2. Заполняем на первом шаге генератора поля api_token и your_reddit_username и нажимаем кружок

    play

    1. Дожидаемся когда 1й шаг завершит работу, жмём такой же кружок на 2м шаге. Минут 10 ждём.
    2. Теперь приложение готово, можно скачать - запускаем кружок на 3м шаге и ждём некоторое время.
    3. Устанавливаем получившийся apk, авторизуемся под своим логином. Проверяем что всё работает.
    4. Обязательно запускаем 4й шаг для удаления созданной виртуальной машины от гугла (где происходила сборка приложения)

    p.s Если вы установите оригинальный Infinity, он будет просить подписку для просмотра контента.


  • Создаём активность на серверах Oracle free tier

    Создаём активность на серверах Oracle free tier

    Надо как то защитить сервер на Oracle, что бы не инстанс не отключали из за новой политики Oracle Reclamation of Idle Compute Instances

    Idle Always Free compute instances may be reclaimed by Oracle. Oracle will deem virtual machine and bare metal compute instances as idle if, during a 7-day period, the following are true:
    
        CPU utilization for the 95th percentile is less than 20%
        Network utilization is less than 20%
        Memory utilization is less than 20% (applies to A1 shapes only)
    

    Хотят нагрузку на cpu - делаем: cpu.js

    import Cpu from "./cpu.js";
    new Cpu(20);
    

    htop


  • Генерируем нейро-котиков

    Генерируем нейро-котиков

    Нашёл интересный промт для midjourney, но он прекрасно переваривается dalle

    cat hacker, computer
    (foggy background, epic realistic, rutkowski, hdr, intricate details, hyperdetailed, cinematic, rim light, muted colors:1.2)
    

    hacker-cat hacker-cat-2 hacker-cat-3 hacker-cat-4 hacker-cat-5 hacker-cat-6


  • Публикуем библиотеку на java в maven-central

    Публикуем библиотеку на java в maven-central

    1. Регистрируемся на issues.sonatype.org
    2. Создаём тикет
      • Поле Issue Type = New Project
      • Summary = Краткое название проекта
      • Group Id = info.x-crm (Это ваш артефакт = имя домена наоборот)
      • Project URL = Ссылка на сайт проекта
      • SCM url = Ссылка на репозиторий
      • Already Synced to Central = No
    3. Ждём пока робот скажет что делать. Можно сразу создать TXT запись для домена с номером тикета OSSRH-XXYYZZ
    4. Скачиваем gpg4win и создаём там приватный ключ, публикуем.
    5. Экспортируем ключ в формате ascii-armored (*.asc)
    6. Создаём файл c:\Users\user.gradle\gradle.properties важный момент
    sonatypeUsername=Логин от issues.sonatype.org
    sonatypePassword=Пароль от issues.sonatype.org
    signingKeyId=Последние 8 цифр идентификатора ключа (short формат)
    signingPassword=Пароль от закрытого ключа
    signingKey=-----BEGIN PGP PRIVATE KEY BLOCK-----\n\nСодержимое ключа в одну строку, где все символы новой строки явно обозначены\n-----END PGP PRIVATE KEY BLOCK-----\n
    
    1. Основные секции файла build.gradle для java приложения. Если в версию добавить слово SNAPSHOT - будет публикация в тестовом maven репозитории.
    plugins {
        id 'java'
        id 'maven-publish'
        id 'signing'
    }
    
    group = 'info.x-crm'
    version = '0.0.1'
    
    java {
        withJavadocJar()
        withSourcesJar()
    }
    publishing {
        publications {
            mavenJava(MavenPublication) {
                artifactId = 'код-этой-библиотеки'
                from components.java
    
                versionMapping {
                    usage('java-api') {
                        fromResolutionOf('runtimeClasspath')
                    }
                    usage('java-runtime') {
                        fromResolutionResult()
                    }
                }
    
                pom {
                    name = 'Название проекта'
                    description = 'Описание проекта'
                    url = 'https://x-crm.info/'
                    licenses {
                        license {
                            name.set("The Apache License, Version 2.0")
                            url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
                        }
                    }
                    scm {
                        connection = 'scm:git:https://github.com/william-aqn/blog.git'
                        developerConnection = 'scm:git:https://github.com/william-aqn/blog.git'
                        url = 'https://github.com/william-aqn/blog'
                    }
                }
            }
        }
        repositories {
            maven {
                def releasesRepoUrl = "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/"
                def snapshotsRepoUrl = "https://s01.oss.sonatype.org/content/repositories/snapshots/"
                url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
                credentials {
                    username = findProperty("sonatypeUsername").toString()
                    password = findProperty("sonatypePassword").toString()
                }
            }
        }
    }
    
    signing {
        def signingKeyId = findProperty("signingKeyId").toString()
        def signingKey = findProperty("signingKey").toString()
        def signingPassword = findProperty("signingPassword").toString()
        useInMemoryPgpKeys(signingKeyId, signingKey, signingPassword)
        sign publishing.publications.mavenJava
    }
    
    1. Если что то пошло не так - тут расшифрованы коды ошибок
    2. Отправляем на релиз публикацию (Нажать close, подождать немного, release)

    Автопубликация библиотеки из репозитория при коммитах

    1. Для Github есть экшен, заполняем секреты sonatypeUsername / sonatypePassword / signingKeyId / signingKey / signingPassword
    2. Для Bitbucket создаём base64 строку из содержимого файла gradle.properties и сохраняем в секрет репозитория
    3. Создаём файл с пайплайном bitbucket-pipelines.yml
    image: gradle:8.0
    
    pipelines:
      default:
        - parallel:
          - step:
              name: Publish
              caches:
                - gradle
              script:
                - echo "$SECRET_BASE64_CONFIG" | base64 -d > ~/.gradle/gradle.properties
                - gradle publish
    

    Рекомендации для библиотеки


  • Как сделать standalone версию java библиотеки

    Как сделать standalone версию java библиотеки и получить независимый jar файл

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

    Делаем таск в build.gradle для java standalone приложения.

    plugins {
        id 'java'
    }
    
    group = 'info.x-crm'
    version = '0.0.1'
    
    tasks.register('standaloneJar', Jar) {
        archiveFileName = "lib-standalone-${version}.jar"
        duplicatesStrategy = DuplicatesStrategy.EXCLUDE
        from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
        with jar
    }
    

  • Быстро переводим текст в буфере обмена

    Быстро переводим текст в буфере обмена

    Когда нужно перевести очень много мелких фраз на разные языки в уникальных местах файлов - очень муторно переключаться между переводчиком. Пусть само всё переводится в буфере!

    Сделал GUI для переводчика и прикрутил на выбор google-free, deepl и openapi с моделью text-davinci-003

    Пока оптимальный промпт для перевода текста это

    Please translate the user message from #from# to #to#. Make the translation sound as natural as possible.
    

    screen

    Скачать можно тут node-clipboard-translate


  • Меняем регион у ASUS роутера

    Меняем регион у ASUS роутера

    Что бы нормально работать с санкционными роутерами, нужно поменять его регион. Первым делом скачиваем прошивку от merlin для своей модели роутера. Включаем доступ по ssh в настройках роутера. Заходим по ssh и вводим команды

    Создаём файл /jffs/scripts/init-start в котором будет меняться регион на US, можно постаить #a - разблокируется вообще всё, но говорят не очень стабильно это.

    nvram set location_code=US
    nvram commit
    service restart_wireless
    

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

    nvram set jffs2_exec=/jffs/scripts/init-start
    nvram set jffs2_scripts=1
    nvram commit
    reboot
    

    После перезагрузки проверяем мощность

    wl txpwr_target_max
    > Maximum Tx Power Target (chanspec:0x1908):      24.00  24.00  24.00  24.00
    

    И регион

    nvram get location_code
    > US
    

    Пример заводского конфига

    Различные изыскания можно почитать тут И отличная статья по измерению мощности на всех каналах

    Или пишите в ЛС @CrashXRU, у него есть приватный способ сделать всё правильно, но делает только сам.

    Так же наставление как делать правильный костыль:

    пишем в nvram 
    CCODE + REV
    каналы и ширину если они отличаются от евро
    перезапускаем радио модуль
    далее проверяем через WL если СС+REV те то проверяем канал, если тот то пропускаем
    Если нет, то выключаем модуль ставим нужные параметры и включаем уже модуль и не службу модулей
    
    тогда все будет работать до перезагрузки
    
    но менять настройки радиомодулей НЕЛЬЗЯ
    поменяли что то не важное, перезагрузили роутер
    
    трогать прошивку нельзя, пытаться записать нельзя все потому что прошивка плоская, те она упакована и только ro сделать ее RW нельзя ну никак, вообще никак, это особеность таких прошивок
    

  • Запущен бот в Telegram

    Запущен бот в Telegram

    @xcrminfo_bot

    Оживил старый функционал по сбору ключей для nod32, теперь уже на nodejs с использованием headless браузера chrome

    Основные команды

    • /who - Информация о id чата и id пользователя
    • /nod - Ключи для nod32 (если найдутся, запрос в гугле - ключи для nod32 и смотрим выдачу)

    Технические подробности можно прочитать в посте - Парсим сайт спрятанный через Cloudflare


  • Парсим сайт спрятанный через Cloudflare

    Парсим сайт спрятанный через Cloudflare

    Нашёл способ обходить проверку cloudflare, но хром жрёт как не в себя оперативку. Отключаем скрипты слежения и всю медиа что есть на страницах. Авторизуемся где нибудь и парсим контент. Ещё плагины можно найти в репозитории puppeteer-extra - например обход рекапчи.

    Не забываем установить chrome

    wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
    sudo apt install ./google-chrome-stable_current_amd64.deb
    
    import puppeteer from 'puppeteer-extra'
    import StealthPlugin from 'puppeteer-extra-plugin-stealth'
    import AdblockerPlugin from 'puppeteer-extra-plugin-adblocker'
    import ResBlockPlugin from 'puppeteer-extra-plugin-block-resources'
    
    class Nod {
        constructor() {
            puppeteer.use(StealthPlugin())
            puppeteer.use(AdblockerPlugin({ blockTrackers: true }))
            puppeteer.use(ResBlockPlugin({ blockedTypes: new Set(['image', 'stylesheet', 'media', 'font']) }))
        }
    
        parse() {
            let keys = [];
            const browser = await puppeteer.launch({
                executablePath: "/usr/bin/google-chrome-stable",
                args: ["--enable-features=NetworkService", "--no-sandbox"],
                ignoreHTTPSErrors: true,
                headless: "new"
            });
            // const browser = await puppeteer.launch({ headless: false })
    
            try {
                const page = await browser.newPage()
                // Открываем страницу
                await page.goto('https://', { timeout: 60000 });
                
                // Авторизуемся где нибудь
                await page.$eval('input[name=vb_login_username]', (el, login) => { el.value = login }, 'Логин какой нибудь');
                await page.$eval('input[name=vb_login_password]', (el, pwd) => { el.value = pwd }, 'Пароль какой нибудь');
                await page.click('input.button[type=submit]');
                await page.waitForNavigation({ waitUntil: 'load' });
    
                // Находим посты
                let messages = await page.$x("//*[contains(@id,'post_message_')]");
                for (let message of messages) {
                    let text = await message.evaluate(element => element.innerHTML);
                    // Находим ключи в постах
                    let k = text.match(/([A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4})/gm);
                    if (k) {
                        keys.push(...k);
                    }
                }
            } catch (e) {
                console.log(e);
            } finally {
                await browser.close();
            }
            return keys;
        } 
    export default Nod;
    

    Это небольшой пример кода моего бота


  • Пробрасываем сессию пользователя в Google Tag Manager

    Пробрасываем сессию пользователя в Google Tag Manager через Measurement Protocol

    1. За основу берём эту статью
    2. Собираем данные с фронта в base64 строку, что бы cloudflare не блокировал этот набор данных.
    function getCookieByPrefix(prefix) {
        let cookies = document.cookie.split(';');
        let searchKey = '';
        for (let i = 0; i < cookies.length; i++) {
          let cookie = cookies[i].trim();
          if (cookie.startsWith(prefix)) {
            let keyValue = cookie.split('=');
            let value = keyValue[0];
            if(value){
                searchKey = value;
            }
          }
        }
        return searchKey;
    }
    
    function getSessionData(id) {
    	let regex = new RegExp(id + "=GS\\d\\.\\d\\.(.+?)(?:;|$)");
    	const match = document.cookie.match(regex);
    	const parts = match?.[1].split(".");
    
    	if (!parts) {
    		window.setTimeout(() => getSessionData(id), 200);
    		return;
    	}
    
    	return parts.shift();
    }
    
    let trueSession_id = ''
    let dataG4 = '';
    let encoded = '';
    try {
        if(!trueSession_id){
            let searchKeyBycookie = getCookieByPrefix('_ga_');
            trueSession_id = getSessionData(searchKeyBycookie) || '';
        }
        dataG4 = {
            "cid": gaGlobal?.vid,
            "sid": trueSession_id,
            'ul':  navigator.language || navigator.userLanguage,
            'sr':  screen.width + 'x' + screen.height,
            'uaa': google_tag_data?.uach?.architecture,
            'uab': parseInt(google_tag_data?.uach?.bitness),
            'uafvl': google_tag_data?.uach?.fullVersionList.map(({ brand, version }) => `${brand};${version}`).join('| '),
            'uap': google_tag_data?.uach?.platform,
            'uapv': google_tag_data?.uach?.platformVersion,
            'cu': window.cur_currency || 'USD',
            'dl': document.location.href,
            'dr': document.referrer || '',
            'dt': document.title,
            'en': 'purchase',
        };
        encoded = Base64.encode(JSON.stringify(dataG4))
        
    } catch(e){
        console.warn(e);
    }
    
    
    1. На бэке сохраняем эти данные в доп.поле к заказу
    2. Для отправки используем библиотеку php-ga4
    3. В итоге должен получиться вот такой набор данных, который отправляется на endpoint https://www.google-analytics.com/mp/collect?measurement_id=G-0*********&api_secret=*********************
      • session_id должен быть числом (т.е. без кавычек в json)
    {
      "non_personalized_ads": false,
      "client_id": "601471748.1686739658",
      "user_properties": {
        "uafvl": {
          "value": "Not.A/Brand;8.0.0.0| Chromium;114.0.5735.60| Google Chrome;114.0.5735.60"
        },
        "uap": {
          "value": "Android"
        },
        "uapv": {
          "value": "8.1.0"
        }
      },
      "events": [
        {
          "name": "purchase",
          "params": {
            "language": "pt-BR",
            "page_location": "https://site.com/",
            "page_referrer": "android-app://org.telegram.messenger/",
            "page_title": "Заголовок страницы",
            "screen_resolution": "360x640",
            "session_id": 1686739658,
            "engagement_time_msec": "1000",
            "currency": "USD",
            "transaction_id": 12399321,
            "value": 45.54,
            "affiliation": "User",
            "coupon": "",
            "shipping": 0,
            "tax": 0,
            "items": [
              {
                "item_id": "123456",
                "item_name": "Название товара",
                "currency": "USD",
                "item_category": "Категория товара",
                "price": 45.54,
                "quantity": 1
              }
            ]
          }
        }
      ]
    }
    

  • Как запустить Diablo 4 в России

    Как запустить Diablo 4 в России

    1. Оригинальный мануал
    2. Купить через подарок где нибудь
    3. Скачать BNetInstaller.exe
    4. Запустить и ввести данные ниже
      TACT Product: fenris
      Agent UID: fenris
      Installation Directory: путь куда нужно установить игру (например, C:\Games\Diablo IV Beta)
      Game/Asset Language: язык игры (ruRU для русской версии или enUS для английской)
      Repair Install (Y/N): N
      

      3.1. Если хотим сами скачать бэту

      TACT Product: fenrisb
      Agent UID: fenris_beta
      

      Или воспользоваться бинарниками из beta_binary.rar, пароль c7148a33d7dea696012adac714b6d4f0

    5. Создаём ярлык с ключём “Diablo IV.exe” -launch
    6. Закидываем из бэты Diablo IV.exe и .build.info в релиз игры, предварительно сохранив оргинальные.
    7. Запускаем через ярлык бэту и авторизуемся
    8. Меняем бинарники обратно
    9. Запускаем через ярлык релиз.

    Ещё есть unlocker.rar, разблокирует запуск через оригинальный battle.net клиент, пароль d84fbe00a685f25c3e3f52db43d63b06 Можно поймать бан за анлокер.


  • Bitrix.DevOps

    Полный цикл CI/CD в bitrix env

    Основная идея Bitrix.DevOps

    • Рабочие копии сайта актуализируются через Action в гите любым разработчиком (~10 минут)
    • У каждого разработчика собственная рабочая копия основного сайта связанная с git на собственной ветке.
    • Все изменения перез релизом отправляются на staging сайт для автоматического тестирования и последующего создания PullRequest в master ветку с уведомлением в телеграмм.
    • Любое изменение файлов на основном сервере, который связан с master веткой отправляется в новую ветку, что бы не потерять изменения внесённые менеджером.
    • Любое изменение файлов на тестовых серверах - откатываются до состояния репозитория

    Это предже всего инструмент, изучите код перед тем как его применить!


  • Великий Китайский Файрвол

    Великий Китайский Файрвол

    За основу брал мануал https://habr.com/ru/articles/735536/

    Панель на сервере https://github.com/alireza0/x-ui

    • Устанаваливаем
      bash <(curl -Ls https://raw.githubusercontent.com/alireza0/x-ui/master/install.sh)
      
    • Если хотим через докер
      docker run -itd \
        -p 127.0.0.1:8181:54321 -p 443:443 -p 80:80 \
        -e XRAY_VMESS_AEAD_FORCED=false \
        -v $PWD/db/:/etc/x-ui/ \
        -v $PWD/cert/:/root/cert/ \
        --name x-ui --restart=unless-stopped \
        alireza7/x-ui:latest
      

    Основные моменты

    • Стандартный логин/пароль - admin/admin меняем на свои
    • В X-UI поле Subscription по умолчанию не отображается, нужно сначала активировать функционал подписок в настройках панели.
    • По умолчанию заблокирован Торрент трафик, разрешаем в настройках.
    • Делаем в настройках панели доступ только через 127.0.0.1

    Настройка Shadowsocks-2022

    Создаем подключение:

    • Remark - Любое название
    • Протокол - Shadowsocks
    • Listening IP - Оставляем пустым
    • Порт - Панель выберет рандомный

    Настраиваем пользователя, других можно добавить позже:

    • Email - Любой текст
    • Subscription - Тот же самый текст.

    Дальше снова идут настройки протокола:

    • Шифрование - выбираем что-нибудь что начинается с 2022
    • Пароль - (ключ) панель сгенерирует автоматически с правильной длиной для выбранного метода шифрования.

    Нажимаем “Создать” и на этом настройка для Shadowsocks закончена, им уже можно пользоваться.

    Настройка VLESS с XTLS-Reality

    Создаем подключение:

    • Remark - Любое название
    • Протокол - vless
    • Listening IP - Оставляем пустым
    • Порт - Обязательно 443

    Далее переходим к настройкам клиента:

    • Email - Любой другой текст
    • Subscription - Текст который указали при настройке в Subscription Shadowsocks-2022
    • Flow - Выбираем “xtls-rprx-vision”. Поле Flow появится только после того, как чуть ниже поставите галочку на пункте Reality.

    Дальше у нас идут настройки транспорта:

    • Reality - Активно
    • XTLS - Отключено
    • uTLS - по умолчанию firefox (главное чтобы не android, могут быть проблемы с клиентами)
    • Домен - Это не домен, а адрес для подключения к вашему серверу. Можно оставить пустым, тогда панель автоматически подставит IP-адрес или домен, по которому вы обращаетесь в панели на сервере.
    • ShortIds - Случайное hex число
    • Public Key, Private Key - Нажимаем Get new keys, и панель сама заполнит эти поля
    • Dest и Server names - это самое интересное, это домен, под который вы будете маскироваться. По умолчанию панель предлагает маскировку под yahoo.com и www.yahoo.com с переадресацией на yahoo.com:443, но лучше выбрать какой-нибудь другой домен

    Клиенты

    • Windows https://github.com/MatsuriDayo/nekoray/releases
      • Ядро выбираем sing-box
      • Тип подключения - VPN Mode
      • Настройка профиля Настройка nekobox
    • Android https://github.com/MatsuriDayo/NekoBoxForAndroid/releases
      • https://4pda.to/forum/index.php?showtopic=1065786
    • IOS https://apps.apple.com/us/app/shadowrocket/id932747118

  • Настраиваем zerotier в lxc контейнере proxmox

    For LXC to work : Enabling tun by default when starting a CT image to get zerotier working :

    on proxmox host Edit this file “/etc/pve/lxc/ctxxx.conf” with these 2 lines which enabled me to get zerotier working on the container, and connect to my zerotier network. After adding the lines, I simply rebooted the ct.

    lxc.cgroup.devices.allow: c 10:200 rwm lxc.mount.entry: /dev/net dev/net none bind,create=dir


  • Подключаем детектор углекислого газа Даджет к Home Assistant

    Подключаем детектор углекислого газа Даджет к Home Assistant (ZyAura ZGm053U CO2 & Temperature Monitor) через ESPHome

    https://esphome.io/components/sensor/zyaura.html

    В наличии был esp01 который идеально подходит к пинам на плате

    И программатор pl2303, которому нужны специальные драйвера, иначе не запустится

    Подключаем для прошивки по схеме pl2303 esp01

    • 3.3V -> VDD+CH_EN
    • TXD -> RXD
    • RXD -> TXD
    • GND -> GND+GPIO_00 Пины

    В Home Assistant создаём прошивку и заливаем на esp через Chrome браузер yaml

    Дальше отключаем GPIO_00 от GND, подключаем к co2 выводам esp01 (пока питание берём от pl2303) В логе появляются данные Источник питания

    Теперь надо отпаять гребёнку от esp01 и поместить esp01 непосредственно на пины co2 Питание 3.3V надо где то взять… Источник питания

    TODO:

    • Найти питание

  • Дорабатываю плагин для The Lord of the Rings Online

    Дорабатываю плагин для The Lord of the Rings Online

    Переработал идею плагина Item Treasury и вот что получилось:

    • Быстрый поиск оригинального названия предмета для аукциона
    • Открытие окна быстрого поиска командой /ru или нажатием правой кнопкой мыши на иконку плагина
    • Регистронезависимый поиск предметов на Русском языке
    • Отображение названий предметов ru/en/ru+en
    • Перевод интерфейса
    • Скрипт для автоматического обновления БД (update.cmd) Изменения для новой версии оригинального плагина можно сделать самостоятельно, в репозитории написано что и где менять. Или update.cmd сделает это сам.

    Можно скачать на translate.lotros.ru или из репозитория

    How to use How to use


  • Double VPN или шифруемся грамотно

    Дабл впн или шифруемся грамотно (никаких докеров и certbotoв)

    Точка входа Cloudflare, точка выхода - ваша vps

    За основу брал мануал https://bernd32.blogspot.com/2022/03/shadowsocksv2ray-tls.html

    1. Покупаем любой домен, или используем свой (если уже есть)
    2. Регистрируемся в Cloudflare и привязываем туда созданный домен
      • Ждём несколько часов, пока DNS-записи обновятся.
      • Зайдём в Firewall Cloudflare и изменим security level на essentially off
    3. Разворачиваем на нашей VPS-ке shadowsocks
      • Все команды выполняются под рутом. sudo su - наше всё
    4. В зависимости от провайдера vps и установленной машины - открываем порты 80 и 443
      • Если у вас Oracle или Amazon - порты открыть дополнительно надо в панели управления самого хостера.
    5. Устанавливаем nginx apt install nginx (если ubuntu)
      • Удаляем дефолтный конфиг: rm /etc/nginx/sites-available/default && sudo rm /etc/nginx/sites-enabled/default
    6. Cоздаем root-директорию, в которой будут находиться файлы нашего сайта sudo mkdir /var/www/<домен>
      • Создаем там файл index.html nano /var/www/<домен>/index.html и записываем туда что угодно, например
       <!DOCTYPE html>
       <html lang="en">
       <head>
       <meta charset="UTF-8">
       <meta http-equiv="X-UA-Compatible" content="IE=edge">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <title>Hello world</title>
       </head>
       <body>
       <h1>Hello world</h1>
       </body>
       </html>
      
    7. Забираем SSL сертификат и приватный ключ у Cloudflare для нашего домена (SSL/TLS->Origin Server) и сохраняем в /nginx/ssl/<домен>/public.key и /nginx/ssl/<домен>/private.key
      • Внимание! Он валидный ТОЛЬКО с Cloudflare. Нужен что бы nginx хорошо себя вёл.
      • Генерируем на нашем сервере openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096
    8. В настройках своего домена на Cloudflare, в разделе SSL/TLS ставим Full(strict).

    9. Создаем конфиг для нашего сайта: nano /etc/nginx/sites-available/<домен>

      • Вставляем (и не забываем вставить свой домен вместо <домен>):
       server {
           server_name <домен>;
      
           root /var/www/<домен>;
           index index.html;
      
           location / {
                   try_files $uri $uri/ =404;
           }
      
           location /bdsm {
               proxy_redirect off;
               proxy_http_version 1.1;
               proxy_pass http://localhost:8008;
               proxy_set_header Host $http_host;
               proxy_set_header Upgrade $http_upgrade;
               proxy_set_header Connection "upgrade";
           }
      
           listen [::]:443 ssl ipv6only=on;
           listen 443 ssl; 
           ssl_certificate /nginx/ssl/<домен>/public.key;
           ssl_certificate_key /nginx/ssl/<домен>/private.key;
           ssl_session_cache shared:le_nginx_SSL:10m;
           ssl_session_timeout 1440m;
           ssl_session_tickets off;
      
           ssl_protocols TLSv1.2 TLSv1.3;
           ssl_prefer_server_ciphers off;
           ssl_dhparam /etc/nginx/ssl/dhparam.pem;
      
           ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
       }
      
       server {
           if ($host = <домен>) {
               return 301 https://$host$request_uri;
           } 
      
           listen 80;
           listen [::]:80;
      
           server_name <домен>;
           return 404;
       }
      
      
    10. Включаем сайт: ln -s /etc/nginx/sites-available/<домен> /etc/nginx/sites-enabled/

      • Рестартим nginx: systemctl restart nginx

      • Вставляем в адресную строку браузера наш домен и проверяем, что всё работает

    11. Устанавливаем shadowsocks (Если у вас x64): Если у вас arm64 см пункт 13

      • Создаем папку под бинарники сс: mkdir /etc/ss-go

      • Качаем бинарник сс с гитхаба: wget https://github.com/shadowsocks/go-shadowsocks2/releases/download/v0.1.5/shadowsocks2-linux.gz

      • Распакуем архив сс-го: gzip -d shadowsocks2-linux.gz

      • Переносим и переименуем бинарник: mv shadowsocks2-linux /etc/ss-go/ss-go

      • Делаем бинарник исполняемым: chmod +x /etc/ss-go/ss-go

      • Повышаем права сс и позволяем ему занимать привилегированные порты: setcap "cap_net_bind_service=+eip" /etc/ss-go/ss-go

    12. Устанавливаем v2ray плагин:

      • Cкачиваем плагин (вместо v1.3.1/v2ray-plugin-linux-amd64-v1.3.1.tar.gz может быть что-то другое, последняя версия лежит тут https://github.com/shadowsocks/v2ray-plugin/releases/latest) wget https://github.com/shadowsocks/v2ray-plugin/releases/download/v1.3.1/v2ray-plugin-linux-amd64-v1.3.1.tar.gz

      • Разархивируем сам плагин, тут опять же может быть другой файл в зависимости от скачиваемой версии: tar -xf v2ray-plugin-linux-amd64-v1.3.1.tar.gz

      • Переносим и переименуем плагин: mv v2ray-plugin_linux_amd64 /etc/ss-go/v2ray-plugin

      • Даем возможность v2ray-плагину занимать привилегированные порты: setcap "cap_net_bind_service=+eip" /etc/ss-go/v2ray-plugin

      • Вставляем следующее (вместо <пароль> нужно придумать пароль): `nano /etc/systemd/system/ss-v2ray.service`

      [Unit]
      Description=Go-shadowsocks2 with V2RAY-websocket obfuscation
      After=network.target
          
      [Service]
      Type=simple
      User=nobody
      Group=nogroup
      LimitNOFILE=51200
      ExecStart=/etc/ss-go/ss-go -s localhost:8008 -password <пароль> -cipher AEAD_CHACHA20_POLY1305 -plugin /etc/ss-go/v2ray-plugin -plugin-opts "server;loglevel=none;path=/bdsm"
      
      [Install]
      WantedBy=multi-user.target
      
      • Сохраняем ctrl + o, закрываем ctrl + x

      • Включаем сервис: systemctl enable ss-v2ray.service

    13. Устанавливаем shadowsocks (Если у вас arm64):
      • Качаем rust версию wget https://github.com/shadowsocks/shadowsocks-rust/releases/download/v1.14.3/shadowsocks-v1.14.3.aarch64-unknown-linux-gnu.tar.xz
      • Берём оттуда ssserver mv ssserver /etc/ss-go/ss-go

      • Делаем бинарник исполняемым: chmod +x /etc/ss-go/ss-go

      • Повышаем права сс и позволяем ему занимать привилегированные порты: setcap "cap_net_bind_service=+eip" /etc/ss-go/ss-go

      • Делаем конфиг nano /etc/ss-go/shadowsocks-rust.json
      {
      "server": "127.0.0.1",
      "server_port": 8008,
      "password": "пароль",
      "timeout": 120,
      "method": "chacha20-ietf-poly1305",
      "no_delay": true,
      "fast_open": true,
      "reuse_port": true,
      "workers": 1,
      "ipv6_first": false,
      "nameserver": "1.1.1.1",
      "mode": "tcp_and_udp",
      "plugin": "/etc/ss-go/v2ray-plugin",
      "plugin_opts": "server;loglevel=none;path=/bdsm"
      }
      
      • Меняем в nano /etc/systemd/system/ss-v2ray.service

    ExecStart=/etc/ss-go/ss-go -c /etc/ss-go/shadowsocks-rust.json

    Настраиваем клиент под windows

    server addr - <домен>
    server port - 443
    password - <пароль>
    encryption - chacha20-ietf-poly1305
    plugin program - v2ray-plugin_windows_amd64.exe
    plugin options - tls;host=<домен>;path=/bdsm
    proxy port - локальный порт куда будем направлять браузер (по дефолту 1080, можно не трогать)
    

    Клиент под android

    1. Устанавливаем https://play.google.com/store/apps/details?id=com.github.shadowsocks
    2. +v2ray https://play.google.com/store/apps/details?id=com.github.shadowsocks.plugin.v2ray

  • Подписываем ЭЦП word/excel/pdf документ

    Подписываем ЭЦП word/excel/pdf документ через криптопровайдера Vipnet CSP без установки КриптоПРО и без физического токена. За 1 день.

    Disclaimer: Нельзя просто так взять и подписать документ, техподдержка говорит дичь (т.е. ничего полезного)

    1. Делаем виртуальную машину на основе ОРИГИНАЛЬНОЙ (не репака) Windows 10 (версия 1607, сборка 14393) https://nnmclub.to/forum/viewtopic.php?t=1042256 magnet:?xt=urn:btih:33897D649002A253918465C0B07009F99D961C15

    2. Устанавливаем Microsoft Office максимальную версию 2013 https://nnmclub.to/forum/viewtopic.php?t=1551670 magnet:?xt=urn:btih:93dd4132850b9280a20758616a6a3e41e81251c6 Иначе получите ошибку
      Аалгоритм шифрования необходимый для выполнения этой операции не установлен на этом компьютере
      

      Тех.поддержка говорит нужен КриптоПро Office Signature 2.0, который в свою очередь требует КриптоПРО CSP, который стоит денег, который конфликтует с бесплатной Vipnet CSP. Итого - нафиг.

    3. Делаем снапшот виртуалки. Это важно!

    4. Устанавливаем ViPNet CSP Win 4.4.2.2388 от 30.07.2021 с отключенной галкой TLS (иначе чёрный экран получите после перезагрузки) https://infotecs.ru/product/vipnet-csp.html

    5. Перезагружаем виртуалку. Если что то пошло не так - откатываемся, и отключаем забытую галку TLS при установке ViPNet CSP.

    6. Покупаем ЭЦП для физ лиц, например тут всего за 900 рублей на 15 месяцев, при покупке обязательно выбираем VipnetCSP https://astral.ru/tarify/astral-et/astral-et-fl/23803/

    7. В течении одного дня проходим различные бюрократические процедуры,

    8. Делаем бэкап криптоконтейнера. А лучше в несколько разных мест.

    9. Делаем снапшот виртуалки, что бы откатываться для сброса Adobe и КриптоПро PDF.

    10. Устанавливаем Adobe DC Pro исключительно версию x86 https://nnmclub.to/forum/viewtopic.php?t=1557398 magnet:?xt=urn:btih:7FC889FDBB22EB6D2A3823F1385F85A4BE075156

    10.1. Adobe Reader DC исключительно версию x86 Выбираем windows 10, Russian, Reader DC 2019.008.20071 Russian for Windows Снимаем галки с McAfee Жмём скачать https://get.adobe.com/ru/reader/otherversions/

    1. Устанавливаем плагин КриптоПро PDF для подписывания pdf, который работает ограниченное время. https://www.cryptopro.ru/products/other/pdf/downloads

    2. В настройках Adobe DC заходим Редактирование->Установки->Подписи->Создание и оформление->Метод подписания по умолчанию = “КриптоПро PDF” + Формат подписания по умолчанию = “Эквивалент CaDES” Иначе получим вот такую ошибку:
      Не удалось закончить создание этой подписи.  
      Ошибка превышения размера.  
      Неподдерживаемый алгоритм открытых ключей
      
    3. Подписываем документы, наслаждаемся. Откатываемся через 90 дней на снапшот, и ставим снова КриптоПро PDF.