dotzero

↑ ↑ ↓ ↓ ← → ← → B A Start

Альбом с улиц Los Angeles

Гуляя вечером по улицам Лос-Анджелеса к нам подошел веселый чернокожий парень и стал расспрашивать откуда мы, а потом сам рассказал свою историю, начинающего артиста. Дойдя до этого места он предложил нам поддержать его, купив альбом на простом CD и даже оставил на нем свой автограф в надежде, что он станет знаменитым.

Мы решили поддержать его и купили тот альбом. Теперь же спустя полтора года я так и не смог найти о нем ничего нового кроме аккаунта в Instagram и решил выложить тот альбом на SoundCloud, чтобы послушать мог каждый.

Сертификаты Let's Encrypt

Let’s Encrypt крут, а вот официальный клиент настолько ужасен, что уже появилось огромное количество альтернативных решений.

Для своих проектов я выбрал acme-tiny и написал инструкцию как автоматизировать перевыпуск сертификатов каждый месяц.

Установка и настройка клиента letsencrypt

  1. Создаем пользователя letsencrypt и необходимые директории:

    adduser --home /var/www/challenges \
        --shell /bin/sh \
        --disabled-password \
        --disabled-login \
        letsencrypt
    mkdir -p /etc/letsencrypt/domains
    
  2. Добавляем пользователя letsencrypt в sudoers для перезагрузки nginx:

    visudo -f /etc/sudoers.d/letsencrypt
    
    letsencrypt ALL=(ALL) NOPASSWD: /usr/sbin/service nginx reload
    
  3. Генерим основные приватные ключи:

    cd /etc/letsencrypt/
    openssl dhparam -out dhparam.pem 2048
    openssl genrsa 4096 > account.key
    
  4. Скачиваем клиент acme_tiny.py:

    cd /var/www/challenges
    wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py
    
  5. Создаем скрипт /var/www/challenges/acme-tiny.sh, для автоматизации. Изменив переменную DOMAINS добавляем имена доменов, которым необходимы сертификаты:

    DOMAINS=( example.com foobar.com )
    DOMAIN_ROOT=/etc/letsencrypt/domains
    ACCOUNT_KEY=/etc/letsencrypt/account.key
    ACME_DIR=/var/www/challenges
    ACME_TINY=${ACME_DIR}/acme_tiny.py
    
    [ -d ${DOMAIN_ROOT} ] || { echo "ERROR: DOMAIN_ROOT dir does not exists"; exit 1; }
    [ -f ${ACCOUNT_KEY} ] || { echo "ERROR: ACCOUNT_KEY not found."; exit 1; }
    [ -d ${ACME_DIR} ] || { echo "ERROR: ACME_DIR dir does not exists"; exit 1; }
    [ -f "$ACME_TINY" ] || { echo "ERROR: ACME_TINY not found."; exit 1; }
    
    wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > ${DOMAIN_ROOT}/intermediate.pem
    
    for DOMAIN in "${DOMAINS[@]}"
    do
      if [ ! -f "${DOMAIN_ROOT}/${DOMAIN}.key" ]; then
        echo "INFO: Generation private key for $DOMAIN";
        openssl genrsa 4096 > ${DOMAIN_ROOT}/${DOMAIN}.key
        openssl req -new -sha256 -key ${DOMAIN_ROOT}/${DOMAIN}.key -subj "/CN=${DOMAIN}" > ${DOMAIN_ROOT}/${DOMAIN}.csr
      fi
    
      echo "INFO: Generation cert for $DOMAIN";
      python ${ACME_TINY} --account-key ${ACCOUNT_KEY} --csr ${DOMAIN_ROOT}/${DOMAIN}.csr --acme-dir ${ACME_DIR} > ${DOMAIN_ROOT}/${DOMAIN}.crt || exit 1
      cat ${DOMAIN_ROOT}/${DOMAIN}.crt ${DOMAIN_ROOT}/intermediate.pem > ${DOMAIN_ROOT}/${DOMAIN}.pem
    done
    
    sudo service nginx reload
    
  6. Устанавливаем права:

    chmod 700 /etc/letsencrypt
    chown -R letsencrypt: /etc/letsencrypt /var/www/challenges
    
  7. Добавляем location в nginx у всех доменов, которым необходимо получать сертификат:

    location /.well-known/acme-challenge/ {
        alias /var/www/challenges/;
        try_files $uri =404;
    }
    
  8. Запускаем:

    su -c 'umask 033; /bin/bash /var/www/challenges/acme-tiny.sh' letsencrypt
    

Настройка автоматического продления

  1. Создаем log файл:

    sudo touch /var/log/acme_tiny.log
    sudo chown letsencrypt: /var/log/acme_tiny.log
    
  2. Добавляем ежемесячную работу в crontab:

    nano /etc/cron.d/letsencrypt
    
    SHELL=/bin/sh
    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
    0 0 1 * * letsencrypt /bin/bash /var/www/challenges/acme-tiny.sh >> /var/log/acme_tiny.log
    

Получаем класс А в Nginx

server {
    listen      443;
    server_name example.com;

    ...

    ssl on;
    ssl_certificate /etc/letsencrypt/domains/example.com.pem;
    ssl_certificate_key /etc/letsencrypt/domains/example.com.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA;
    ssl_session_cache shared:SSL:50m;
    ssl_dhparam /etc/letsencrypt/dhparam.pem;
    ssl_prefer_server_ciphers on;

    ...
}

Riga

Подпольный рынок кардеров. Перевод книги «Kingpin»

На хабре вышла серия постов с переводом книги Kingpin, читать которую с экрана ноутбука мне совершенно не удобно, и единственным логичным решением стал перевод книги в PDF для чтения на планшете.

Кевин Поулсен, редактор журнала WIRED, а в детстве blackhat хакер Dark Dante, написал книгу про «одного своего знакомого».

В книге показывается путь от подростка-гика, до матерого киберпахана, а так же некоторые методы работы спецслужб по поимке хакеров и кардеров.

Задавшись такой идеей я перевел все посты в отдельные markdown файлы, внес все уточнения из комментариев к постам. А завершающим этапом прогнал все файлы через Яндекс.Спеллер для исправления грубых орфографических ошибок.

Теперь имея материал для работы, сел и написал скрипт на питоне, собирающий из этого набора файлов единый PDF файл. Вначале markdown файлы конвертируем в соответствующие им html страницы.

CHAPTERS = sorted([os.path.join(APP_PATH, f) for f in glob(CHAPTERS_PATH)])

md = Markdown(output_format="html5")

for chapter in CHAPTERS:
    html = md.reset().convert(open(chapter, 'r').read().decode('utf-8'))
    outhtml = TEMPLATE % html

    filename = os.path.splitext(os.path.basename(chapter))[0] + '.html'
    filepath = os.path.join(HTML_PATH, filename)

    with open(filepath, 'w') as f:
        f.write(outhtml.encode('utf-8'))

А на втором этапе установив в систему wkhtmltopdf и библиотеку python-pdfkit собираем из этого набора файлов готовый PDF.

htmlfiles = [os.path.join(HTML_PATH, f) for f in os.listdir(HTML_PATH) if f.endswith('.html')]

options = {
    'page-size': 'B5', # A5
    'margin-top': '0.75in',
    'margin-right': '0.75in',
    'margin-bottom': '0.75in',
    'margin-left': '0.75in',
    'encoding': 'UTF-8',
    'no-outline': None,
    'no-background': None,
}

pdfkit.from_file(htmlfiles, 'kingpin_ru.pdf', options=options, cover='static/cover.html')

Ссылку на готовый скрипт, а также все markdown файлы я выложил на Github. А приготовить PDF в домашних условиях можно выполнив:

git clone https://github.com/dotzero/Kingpin.git
cd Kingpin
pip install -r requirements.txt
python build_pdf.py

А чтобы не останавливаться на достигнутом, сделал еще и EPUB версию, сделать ее также просто:

git clone https://github.com/dotzero/Kingpin.git
cd Kingpin
pip install -r requirements.txt
python build_epub.py

Ссылки на готовые книги:

Как я продавал домены через escrow

За последний месяц мне удалось продать два домена воспользовавшись китайским и американским escrow сервисами. Об опыте продажи и отличии сервисов я и хотел бы рассказать.

Сервис escrow выступает доверенной стороной в сделке между продавцом и покупателем, и, посредством залогов, страхует от недобросовестного выполнения условий.

Первый домен я продал очень настойчивому китайцу с фамилией «杨», который просил чтобы сделка была проведена именно через китайский сервис DN.com.

Решив не упускать возможность попробовать в работе китайский сервис я не стал ему отказывать. Наблюдения по работе с сервисом я выписал в список, а процесс от начала сделки до вывода средств на PayPal занял 4 дня.

  • Для активации аккаунта необходима загрузка двух фотографий: скан ID (паспорт, права и т.д.) и фотография себя держащего этот ID;
  • После внесения оплаты покупателем, сервис помогает в передаче AuthCode домена;
  • Денежные средства можно вывести в $, € или ¥ на PayPal или банковский счет;
  • Комиссию снимают два раза, первый раз с покупателя, за сделку, а второй раз с продавца, за вывод денежных средств;
  • При выводе денег через PayPal, комиссия составила $20, против $25-30 за вывод на банковский счет.

Продавая другой домен я предложил воспользоваться американским сервисом Escrow.com, чтобы иметь представление об отличии от китайского. Процедура затянулась из-за проблем с трансфером домена. Но это не помешало выписать основные различия сервисов.

  • В отличии от DN.com, сервис Escrow.com не требует подтверждение личности, а перед получением денег от покупателя проводится телефонное интервью с продавцом. Основная тема интервью — точное название домена и сумма сделки;
  • После внесения оплаты покупателем сервис никак не помогает в передаче AuthCode домена. А процесс передачи кода должен вестись напрямую с покупателем, по электронной почте;
  • Вывод денежных средств возможен только на банковский счет, комиссия составляет $40, что в два раза превышает китайский сервис.
  • Кроме того, нет возможности держать денежные средства, и сразу по завершению сделки деньги переводятся на банковский счет.

Итого, кроме отсутствия подтверждение личности Escrow.com не предоставляет никаких сервисных преимуществ, имея при этом два раза большую комиссию.