Копируем S3 баккет между AWS аккаунтами

S3

Предположим, что нам надо скопировать данные из баккета в одном аккаунте, в баккет в другом аккаунте, да еще и в другом регионе.

Что нам понадобится

  • Два AWS аккаунта (один для исходного баккета, второй для баккета назначения)
  • IAM пользователь в аккаунте с баккетом, куда мы будем копировать данные (тут есть документация, как создать IAM пользователя в аккаунте)
  • Настроенная утилита aws-cli на локальной машине с ключами ранее созданного пользователя (документация по утилите)

Шаг 1: Получаем номер аккаунта

Заходим в аккаунт назначения. Переходим в SupportSupport center и копируем номер аккаунта.

Шаг 2: Настраиваем исходный S3 баккет

Заходим в аккаунт-источник. Создаем баккет источник (если его еще не было, то что вы тут делаете? ;) документация как создать баккет). Аттачим полиси, которое представлено ниже (как приаттачить полиси). Если вы только создали баккет, то залейте несколько файлов туда для теста.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DelegateS3Access",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::DESTINATION_BUCKET_ACCOUNT_NUMBER:root"
            },
            "Action": [
                "s3:ListBucket",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::SOURCE_BUCKET_NAME/*",
                "arn:aws:s3:::SOURCE_BUCKET_NAME"
            ]
        }
    ]
}

Шаг 3: Настраиваем баккет назначения

Заходим в аккаунт назначения. Создаем баккет, куда будем копировать данные.

Шаг 4: Аттачим полиси к созданному пользователю

Аттачим к созданному пользователю полиси, которое представлено ниже (как приаттачить полиси пользователю).

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::SOURCE_BUCKET_NAME",
                "arn:aws:s3:::SOURCE_BUCKET_NAME/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::DESTINATION_BUCKET_NAME",
                "arn:aws:s3:::DESTINATION_BUCKET_NAME/*"
            ]
        }
    ]
}

Шаг 5: Синхронизируем данные

Если вы сделали все шаги, описанные выше, то можно начать синхронизацию.

aws s3 sync s3://SOURCE-BUCKET-NAME s3://DESTINATION-BUCKET-NAME --source-region SOURCE-REGION-NAME --region DESTINATION-REGION-NAME

Добавляем memcached в стэк Wordpress by Bitnami

wordpress

Понадобилось мне тут в проекте добавить поддержку Memcached в Wordpress, развернутый на Amazon. Кто не в курсе, то там используется предустановка от Bitnami. Поскольку в этом стэке используется не системный PHP, а кастомный, то и добавить туда модуль PHP не тривиальная задача. При попытке использовать доку от Bitnami я получил кучу ошибок и перерыл кучу форумов, чтоб их решить. В результате все мои изыскания вылились в простой скрипт, который все ставит и перезапускает php-fpm.

export LIBMEMCACHED_VERSION='1.0.18'
export PHPMEMCACHED_VERSION='2.2.0'

# Install dependencies

sudo apt update
sudo apt install -y memcached
sudo apt install -y build-essential libtool autoconf unzip wget git pkg-config

# Create folder

sudo mkdir /opt/bitnami/common
sudo chmod 777 /opt/bitnami/common/

# Setup libmemcached

cd /tmp
wget https://launchpad.net/libmemcached/1.0/${LIBMEMCACHED_VERSION}/+download/libmemcached-${LIBMEMCACHED_VERSION}.tar.gz
tar -zxf libmemcached-${LIBMEMCACHED_VERSION}.tar.gz
cd libmemcached-${LIBMEMCACHED_VERSION}
./configure --prefix=/opt/bitnami/common
make
sudo make install

# Setup php extension

cd /tmp
export PHP_AUTOCONF=/usr/bin/autoconf
export PHP_PREFIX=/opt/bitnami/php
wget http://pecl.php.net/get/memcached-${PHPMEMCACHED_VERSION}.tgz
tar -xzf memcached-${PHPMEMCACHED_VERSION}.tgz
cd memcached-${PHPMEMCACHED_VERSION}
/opt/bitnami/php/bin/phpize
./configure --enable-memcached --with-zlib-dir=/opt/bitnami/common --with-libmemcached-dir=/opt/bitnami/common --with-php-config=/opt/bitnami/php/bin/php-config --disable-memcached-sasl
make
sudo make install
echo 'extension=memcached.so' | sudo tee -a /opt/bitnami/php/etc/php.ini

# Restart php-fpm

sudo /opt/bitnami/ctlscript.sh restart php-fpm

iRedMail и “+” в адресе

iredmail

Я как-то давно отказался от услуг Google в плане почты и переехал на свой сервер. Одно время пользовался решением в docker’e, но там было не все гладко. В результате поднял свой сервер и поставил туда iRedMail. Это оказалось сильно дешевле, чем платить сторонним сервисам.

Но там мне не хватало одной очень удобной возможности — добавление символа “+” после имени пользователя, чтоб была возможность фильтрации по получателю. Это очень удобно, т.к. для каждого сервиса можно завести свой индивидуальный почтовый ящик. Что, в свою очередь, помогает идентифицировать утечку. ;)

Итак, что надо сделать, чтоб получать почту в свой ящик, отправленную на адреса вида “[email protected]”.

Открываем файл /etc/postfix/mysql/virtual_alias_maps.cf и меняем там одну строку.

Было:

query       = SELECT ... WHERE forwardings.address='%s' AND ...

Стало:

query       = SELECT ... WHERE forwardings.address=CONCAT(SUBSTRING_INDEX('%u', '+', 1), '@%d') AND ...

Перезагружаем Postfix и наслаждаемся. :)

Merge git-crypted files

git-crypt

Давно искал как получить возможность мерджить файлы, которые зашифрованы git-crypt.

В результате нашел вот такое решение.

Во-первых, добавьте в .gitattributes параметр merge=git-crypt для всех файлов, управляемых git-crypt:

crypt/** filter=git-crypt diff=git-crypt merge=git-crypt

затем добавьте в конец файла .git/config следующее:

[merge "git-crypt"]
    name = A custom merge driver used to merge git-crypted files.
    driver = ./my-merge-tool.sh %O %A %B
    recursive = binary

и, наконец, создать файл в корне repo my-merge-tool.sh содержащий:

ancestor_decrypted="$1__decrypt"
current_decrypted="$2__decrypt"
other_decrypted="$3__decrypt"
echo ""
echo "###########################"
echo "# Git crypt driver called #"
echo "###########################"
echo ""

echo "Decrypting ancestor file..."
cat $1 | git-crypt smudge > "${ancestor_decrypted}"
echo "Decrypting current file..."
cat $2 | git-crypt smudge > "${current_decrypted}"
echo "Decrypting other file..."
cat $3 | git-crypt smudge > "${other_decrypted}"
echo ""

echo "Merging ..."
git merge-file -L "current branch" -L "ancestor branch" -L "other branch" "${current_decrypted}" "${ancestor_decrypted}" "${other_decrypted}"
exit_code=$?
cat "${current_decrypted}" | git-crypt clean > $2

echo "Removing temporary files..."
rm "${other_decrypted}" "${ancestor_decrypted}" "${current_decrypted}"

if [ "$exit_code" -eq "0" ]
then
    echo "@@@ No conflict!"
else
    echo "@@@ You need to solve some conflicts..."
fi

exit $exit_code

и убедитесь, что он выполним:

chmod +x my-merge-tool.sh

Это все, теперь вы можете делать merge, cherry-pick, использовать свой любимый mergetool, как обычно!

Заставляем GitX подписывать коммиты

Я часто использую GitX, как вариант замены коммандной строки, т.к. в нем удобно добавлять несколько коммитов один за одним, выбирая разные файлы или группы файлов. Но вот незадача, он не умеет ставить на commit GPG подпись. Т.е. получается в истории коммитов часть подписана, а часть нет. Некрасиво.

Чтож, научить его это делать несложно, если написать простой wrapper.

Для начала в .gitconfig добавляем такие строки:

[commit]
  gpgsign = true

Теперь создаем враппер по пути что-то типа ~/bin/gitx-signed-commit с содержимым:

1
2
3
4
5
6
7
8
9
#!/usr/bin/env bash

args=("[email protected]")

if [[ "$1" = "commit-tree" ]] && [[ "$(git config --get commit.gpgsign)" = "true" ]]; then
  args=("commit-tree" "-S" "${args[@]:1}")
fi

git "${args[@]}"

Даем права на запуск:

$ chmod 755 ~/bin/gitx-signed-commit

Осталось подключить в GitX. Для этого идем в настройки, выбираем вкладку General, тыкаем на Git Executable и выбираем наш скрипт.

Все. С этого момента все коммиты будут подписываться корректно.

Очистка смердженных веток

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

Пришлось что-то придумывать.

Нет ничего лучше для этой цели, как алиасы в git. Итак, для начала разберем, что надо делать, а потом напишем алиас.

Первое - это забираем и подчищаем ветки из remote:

$ git fetch -p

Теперь можно посмотреть уже смердженные ветки:

$ git branch --merged

В результате мы получим все смердженные ветки, но в списке будет и master. Надо будет его отфильтровать.

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

$ git branch -d branch_name

Собираем это все в алиас. В ~/.gitconfig добавляем строку в секцию [alias]:

[alias]
    cleanup = "!git checkout master && git fetch -p && git branch --merged | grep -v '* ' | xargs -I {} git branch -d {}"

просто используем:

$ git cleanup

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

Nginx + Brotli компрессия

Brotli  алгоритм сжатия данных с открытым исходным кодом,
разработанный Юрки Алакуйяла (фин. Jyrki Alakuijala)
и Золтаном Сабадка.

По сравнению с классическим алгоритмом deflate
(середина 1990-х, ZIP, gzip), brotli, как правило, достигает
на 20 % более высокую степень сжатия для текстовых файлов,
сохраняя сходную скорость сжатия и распаковки. Сжатые при
помощи brotli потоки получили тип кодирования br.

Было бы не плохо использовать этот алгоритм для ускорения отдачи контента своего сайта. Не находите? Давайте сделаем это.

Для начала переходим в каталог /tmp:

cd /tmp

Ставим все, что нам понадобится для сборки:

apt install build-essential git wget libssl-dev libpcre3-dev \
zlib1g-dev libxml2-dev libxslt-dev libgd-dev libgeoip-dev \
libperl-dev -y

Читать далее...

sudo по отпечатку в MacOS

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

Крайне редко, но все же приходится запускать что-то из под sudo. Приходится вводить пароль, а он не маленький и довольно сложный.

В общем, нашел способ не вбивать пароль при запуске sudo, а использовать датчик отпечатка пальца. Делюсь.

Надо поправить файл /etc/pam.d/sudo, добавив в него первой строкой:

auth       sufficient     pam_tid.so

Вы не поверите... Это все. ;)

Сброс пароля пользователя root в MySQL

Сбросить пароль для пользователя root в MySQL не просто, а очень просто. Для этого надо остановить базу:

$ sudo service mysql stop

Теперь запустим базу без проверки привилегий:

$ sudo mysqld_safe --skip-grant-tables &

Теперь можно зайти в базу и поправить пароль:

$ mysql -u root

После этого будет доступна консоль MySQL. Выполняем обновление пароля:

mysql> SET PASSWORD FOR root@'localhost' = PASSWORD('password');

Иногда установка нового пароля заканчивается ошибкой:

ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement

Это ошибка в MySQL и тогда пароль можно установить другой командой:

mysql> UPDATE mysql.user SET authentication_string=password('password') WHERE user='root';

Дальше сбрасываем привилегии и перезапускаем сервер в нормальном режиме:

mysql> FLUSH PRIVILEGES;
mysql> exit;
$ sudo mysqladmin -u root -p shutdown
$ sudo service mysql start

Теперь можно логиниться в базу обычным образом:

$ mysql -u root -p

Настройка DNSSEC в Bind 9.9+

DNSSEC (англ. Domain Name System Security Extensions) — набор расширений IETF протокола DNS, позволяющих минимизировать атаки, связанные с подменой DNS-адреса при разрешении доменных имён. Он направлен на предоставление DNS-клиентам (англ. термин resolver) аутентичных ответов на DNS-запросы (или аутентичную информацию о факте отсутствия данных) и обеспечение их целостности. При этом используется криптография с открытым ключом. Не обеспечивается доступность данных и конфиденциальность запросов. Обеспечение безопасности DNS критически важно для интернет-безопасности в целом.

Правда ведь, что мы хотим быть уверенными, что наш DNS никто не подменит (на самом деле не факт)?

Давайте разберемся как нам сделать свой DNS сервер немного более надежным. Это не гарантирует полной безопасности. Но в общем случае - будет полезно.

Фокус в том, что тот же 8.8.8.8 проверяет DNSSEC и перестает резолвить домены, если цифровая подпись нарушена. Не очень знаю на счет 1.1.1.1, но мне кажется, что он ведет себя так же. А вот если клиент использует провайдерский DNS, который не проверяет целостность данных, то вот тут уже возможна подмена.

В общем, решайте, надо оно вам или нет... А я расскажу, как это реализовать.
Читать далее...