Компания
361,67
рейтинг
10 апреля 2015 в 12:05

Разное → Разбор всех заданий отборочной игры Yandex.Root

Сегодня ночью завершилась первая игра отборочного тура Yandex.Root — олимпиады для Unix-инженеров и системных администраторов. В ней приняло участие 456 человек из 229 команд, 194 из которых выполнили хотя бы одно задание. Со всеми девятью справилось 38 команд.

Мы проводим Root в четвёртый раз, но впервые решили опубликовать на Хабре разбор тасков. Задачи, которые мы даём на олимпиаде, сопоставимы с теми, что регулярно решают наши системные администраторы. В Яндексе почти каждый день что-то выкатывается и, когда что-то идёт не так, нужно оперативно распознать это и эффективно отреагировать.



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

Мы будем благодарны, если вы нам об этом расскажете и поделитесь своим мнением, как сделать лучше. Кстати, если хотите, то можете и попробовать себя в реальной игре. Вторая часть первого тура пройдёт через четыре дня — во вторник 14 апреля, и на неё ещё можно зарегистрироваться.

Игра Shannon


Мы решили назвать все игры в память о людях, которые внесли вклад в современные технологии, которые используются в нашей работе. Эта посвящена Клоду Шеннону, инженеру и математику, который среди прочего подарил нам слово «бит». Кстати, сам сервис root.yandex.ru запущен на compute узлах private cloud Яндекса.

Цель отборочной игры — решить несколько проблем на виртуальной машине, изменив конфигурацию установленной ОС: например, запустить службу или скорректировать работу программы. Задачи могут быть как связанными, так и независимыми. Необходимо «зачистить мониторинг», то есть решить проблемы со статусом Critical (отмечены красным цветом) внутри виртуальной машины. Ее образ можно скачать заранее, образ зашифрован — ключ для расшифровки публикуется и рассылается всем участникам по электронной почте в начале игры.

После расшифровки образа необходимо установить соединение с игровым VPN. Для этого всем участникам выдается config-файл: капитан получает его по почте в момент одобрения заявки, члены команды — когда принимают приглашение капитана. В случае утраты файл можно скачать повторно командой «download». Каждый игрок может подключиться к VPN со своей виртуальной машины, поэтому задачи можно распределять внутри команды и решать их параллельно.

Base


В качестве операционной системы в этой игре используется ArchLinux. После загрузки ОС пользователь видит приглашение «shannon login:». Никаких подсказок относительно реквизитов доступа у игрока нет. Как правило, в таких случаях нужно воспользоваться наличием «физического» доступа к машине и сбросить пароль суперпользователя:

  • перезагружаемся, останавливаем таймер обратного отсчёта в загрузчике Grub;
  • нажимаем 'e', находим строчку linux …, дописываем в конец init=/bin/bash;
  • нажимаем Ctrl-X, ждём загрузки;
  • вводим команду passwd, устанавливаем новый пароль;
  • вводим команду exec /sbin/init, загрузка продолжается.

После выполнения этой процедуры можно войти в систему с новым паролем.

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

  • синхронизируемся с внешним зеркалом: pacman-Sy, pacman-key --populate;
  • обновляем пакетный менеджер: pacman -S pacman, pacman-db-upgrade;
  • для решения некоторых заданий нам понадобится tcpdump и strace:
    pacman -S tcpdump strace.


Внутри игрового образа находится программа game, которая запускает проверочные скрипты (далее — проверки) на удалённом сервере. В случае успешного выполнения проверки, игра засчитывает выполнение задания.

Чтобы обеспечить связность с удалённым сервером, нужно настроить OpenVPN. Организаторы уже подготовили всё необходимое — достаточно скопировать файл конфигурации (он прикреплён к письму от Yandex.Root) в /etc/openvpn/openvpn.conf и выполнить команду systemctl start openvpn@openvpn.

1.SSL


Это задание было решено первым из всех. Справилась с ним команда SudariLudari. В задаче требуется сгенерировать сертификат, подписанный заданным сертификатом удостоверяющего центра.

Set up a webserver with SSL
Here is a private key and a certificate for a CA to generate your certificate:
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCjKwGnBHUwQtTzLb5uhrh+eRRAQyQwGzCg+n4XWzt8M+iX/OGx
4QCG4GjKhi9Nqzhm41+AjPB5cndU3Oe5j1LrcvWvxe2n15FG7hPSLG5dHe97pzpj
KVma8OkcrUc6WWIccZ48FlV21ZCeUFukthtqEDDEEw1CxEnwHgIydnynlwIDAQAB
AoGADTAfrREmK6VrMtCCsMpAxTAiG+ORXDYGYyx73oVoNGy5ovc0gr0N3tjqf1wD
HML3BxHfmTNLCHXhAUHtlMjpya7kkJELurrFgEQ9gkcdogcf8Iw/J6GjBpJG2WlX
vVL4zEiYw0T5TULGI54Iest0ZQx88EX8r+6x1jI668RHCtECQQDYUPLf2K/0FUyk
csXoKq1ECseSVpfhG5NITqsLOc93jh3xAQFYtSuM7E3CeHkP+ZoKY/SGd9QkWrhd
QQFoGL5vAkEAwRoCwNqlUWwTVayGdgw/D/mxtFelKRYl8kj50MeMraBqHM/ijXZt
+wF5exUmuPio+nF64UIqLA1VCYhnqJ49WQJAL3DJY0hdhnVpYqN9PeamK0cF79Un
6AmpKnF+V67tDjZP4LwstGy/SV/FygGr41IFc4Pqa9c54mM3DdSk31SV5wJAHW9f
mBI8PQsib17bKEd5nW/MfNcXYAn2QtaI7iBc+2KGilnOCQ5SeX6iC/cPbgbJi1Od
DZVOZGSr38YhNvzYEQJBALoFJQEg6Xj44ClcJFIjbA+xyipk4h5JcmGvpUeKfaKF
EBSJMECLR8wIa5XUkeRuM30JhTkd0s3WPUFaoBAvcvs=
-----END RSA PRIVATE KEY-----

-----BEGIN CERTIFICATE-----
MIIDHzCCAoigAwIBAgIJALEwbIlKhnreMA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNV
BAYTAlJVMQ8wDQYDVQQIEwZNb3Njb3cxDzANBgNVBAcTBk1vc2NvdzEPMA0GA1UE
ChMGWWFuZGV4MQ0wCwYDVQQLEwRSb290MRgwFgYDVQQDEw9yb290LnlhbmRleC5j
b20wHhcNMTUwNDA2MTY0MzA5WhcNMTYwNDA1MTY0MzA5WjBpMQswCQYDVQQGEwJS
VTEPMA0GA1UECBMGTW9zY293MQ8wDQYDVQQHEwZNb3Njb3cxDzANBgNVBAoTBllh
bmRleDENMAsGA1UECxMEUm9vdDEYMBYGA1UEAxMPcm9vdC55YW5kZXguY29tMIGf
MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCjKwGnBHUwQtTzLb5uhrh+eRRAQyQw
GzCg+n4XWzt8M+iX/OGx4QCG4GjKhi9Nqzhm41+AjPB5cndU3Oe5j1LrcvWvxe2n
15FG7hPSLG5dHe97pzpjKVma8OkcrUc6WWIccZ48FlV21ZCeUFukthtqEDDEEw1C
xEnwHgIydnynlwIDAQABo4HOMIHLMB0GA1UdDgQWBBQG+ykV13EVW9XxCTncLjLV
YVX83TCBmwYDVR0jBIGTMIGQgBQG+ykV13EVW9XxCTncLjLVYVX83aFtpGswaTEL
MAkGA1UEBhMCUlUxDzANBgNVBAgTBk1vc2NvdzEPMA0GA1UEBxMGTW9zY293MQ8w
DQYDVQQKEwZZYW5kZXgxDTALBgNVBAsTBFJvb3QxGDAWBgNVBAMTD3Jvb3QueWFu
ZGV4LmNvbYIJALEwbIlKhnreMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
gYEAmvNk8iAbV4+YMq/9oxkMeB6RxLs9m6jhYyAPuAI/dUhWSX+D+BnRcbsHWK4r
a9G/riM1zerb5BD1apMz3faON2ydFJGB0thjlgr/KXfgaUXjp15QslEhsyhZIgEB
Tak+0BQkkh5+cFAvJhGCZqajr6m2I8Dix3mF3Ey7nSx1GDU=
-----END CERTIFICATE-----

Запишем данные из задания в файлы ca.crt и ca.key соответственно. Теперь посмотрим на сертификат удостоверяющего центра:

# openssl x509 -in ca.crt -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 12767824280512002782 (0xb1306c894a867ade)
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=RU, ST=Moscow, L=Moscow, O=Yandex, OU=Root, CN=root.yandex.com
        Validity
            Not Before: Apr  6 16:43:09 2015 GMT
            Not After : Apr  5 16:43:09 2016 GMT
        Subject: C=RU, ST=Moscow, L=Moscow, O=Yandex, OU=Root, CN=root.yandex.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (1024 bit)
                Modulus:
                    00:a3:2b:01:a7:04:75:30:42:d4:f3:2d:be:6e:86:
                    b8:7e:79:14:40:43:24:30:1b:30:a0:fa:7e:17:5b:
                    3b:7c:33:e8:97:fc:e1:b1:e1:00:86:e0:68:ca:86:
                    2f:4d:ab:38:66:e3:5f:80:8c:f0:79:72:77:54:dc:
                    e7:b9:8f:52:eb:72:f5:af:c5:ed:a7:d7:91:46:ee:
                    13:d2:2c:6e:5d:1d:ef:7b:a7:3a:63:29:59:9a:f0:
                    e9:1c:ad:47:3a:59:62:1c:71:9e:3c:16:55:76:d5:
                    90:9e:50:5b:a4:b6:1b:6a:10:30:c4:13:0d:42:c4:
                    49:f0:1e:02:32:76:7c:a7:97
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                06:FB:29:15:D7:71:15:5B:D5:F1:09:39:DC:2E:32:D5:61:55:FC:DD
            X509v3 Authority Key Identifier: 
                keyid:06:FB:29:15:D7:71:15:5B:D5:F1:09:39:DC:2E:32:D5:61:55:FC:DD
                DirName:/C=RU/ST=Moscow/L=Moscow/O=Yandex/OU=Root/CN=root.yandex.com
                serial:B1:30:6C:89:4A:86:7A:DE

            X509v3 Basic Constraints: 
                CA:TRUE
    Signature Algorithm: sha1WithRSAEncryption
         9a:f3:64:f2:20:1b:57:8f:98:32:af:fd:a3:19:0c:78:1e:91:
         c4:bb:3d:9b:a8:e1:63:20:0f:b8:02:3f:75:48:56:49:7f:83:
         f8:19:d1:71:bb:07:58:ae:2b:6b:d1:bf:ae:23:35:cd:ea:db:
         e4:10:f5:6a:93:33:dd:f6:8e:37:6c:9d:14:91:81:d2:d8:63:
         96:0a:ff:29:77:e0:69:45:e3:a7:5e:50:b2:51:21:b3:28:59:
         22:01:01:4d:a9:3e:d0:14:24:92:1e:7e:70:50:2f:26:11:82:
         66:a6:a3:af:a9:b6:23:c0:e2:c7:79:85:dc:4c:bb:9d:2c:75:
         18:35

Запросим новый сертификат с теми же значениями:

# openssl req -out cert.csr -new -nodes

Country Name (2 letter code) [AU]:RU
State or Province Name (full name) [Some-State]:Moscow
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Yandex
Organizational Unit Name (eg, section) []:Root
Common Name (e.g. server FQDN or YOUR name) []:10.0.0.15
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Подготовим структуру для работы удостоверяющего центра:

# mkdir /etc/ssl/newcerts
# echo 01 > /etc/ssl/serial
# touch /etc/ssl/index.txt

Следующая команда вернёт ошибку, текст которой не столь очевиден:

# openssl ca -cert ca.crt -keyfile ca.key -in cert.csr -out cert.crt
Using configuration from /etc/ssl/openssl.cnf
Check that the request matches the signature
Signature ok
The stateOrProvinceName field needed to be the same in the
CA certificate (Moscow) and the request (Moscow)

На самом деле, проблема заключается в том, что строки в сертификате
удостоверяющего центра и запросе написаны в разных кодировках. Чтобы обойти эту проблему, следует отредактировать файл /etc/ssl/openssl.cnf и изменить значение параметра string_mask в секции [req] на pkix.

Осталось подготовить файлы для веб-сервера:

# mv privkey.pem cert.key
# cat ca.crt >> cert.crt

Теперь установим веб-сервер (pacman -S nginx) и включим SSL в /etc/nginx/nginx.conf%, раскомментировав соответствующую секцию server{}.

Проверяем:

# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# systemctl restart nginx

Но решение не принимается проверяющей системой с диагностикой «SSLv3 is weak». Изменим конфигурацию на рекомендуемую Mozilla:

  • отметим опции Nginx и Modern, вставим конфигурацию в nginx.conf;
  • сгенерируем параметры Диффи-Хеллмана: openssl dhparam -out dhparam.pem -outform PEM -2 2048;
  • перезапустим nginx: systemctl restart nginx.

2.MariaDB repair


В этом задании требуется восстановить работу базы данных.

There is a MariaDB database in /var/lib/mysql. We had access there with login 'checker' and password 'masterkey', but something went wrong.
BTW, the `data` table structure was:
  
  +-------+---------+------+-----+---------+-------+
  | Field | Type    | Null | Key | Default | Extra |
  +-------+---------+------+-----+---------+-------+
  | name  | text    | YES  |     | NULL    |       |
  | hits  | int(11) | YES  |     | NULL    |       |
  | size  | int(11) | YES  |     | NULL    |       |
  +-------+---------+------+-----+---------+-------+


Из названия очевидно, что используется база данных MariaDB, известный форк MySQL.

Установим СУБД: pacman -S mariadb и попробуем запустить systemctl start mysqld. Из логов видно, что mysqld ищет файлы в неправильном месте. Из файла конфигурации /etc/mysql/my.cnf видно, что работа системы в сетевом режиме нарушена — добавлены параметры skip-networking, bind-address, указано неправильное значение datadir. Чтобы сэкономить время, не будем пытаться чинить файл конфигурации; вместо этого заменим его на заведомо рабочий:

[mysqld]
key_buffer_size = 16M
max_allowed_packet = 1M
table_open_cache = 64
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M
tmpdir = '/var/tmp'

Поправим владельца файлов — chown -R mysql:mysql /var/lib/mysql, и попробуем запустить базу данных ещё раз — systemctl restart mysqld.

Ура, mysqld работает. Попробуем подключиться:
# mysql
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

Видим, что установлена парольная защита, а пароль нам неизвестен/ Значит, как и в случае с операционной системой, придётся сбросить его:

  • останавливаем mysqld: systemctl stop mysqld;
  • подготавливаем файл с инструкцией сброса: echo "UPDATE mysql.user SET password = PASSWORD('root') where user = 'root';" > /tmp/reset.sql;
  • запускаем mysqld с загрузкой нашего файла: mysqld --user=mysql --init-file=/tmp/reset.sql;
  • теперь остановим mysqld штатным образом, для этого следует нажать Ctrl-\;
  • запустим unit снова — systemctl start mysqld

После выполнения этой процедуры мы уже можем подключиться к базе данных с паролем root. Попробуем: mysql -ppassword -uroot. Из вывода команды show databases видим факт существования базы db, но в ней нет таблицы data. Однако же, эта таблица есть на диске (/var/lib/mysql/db/data.ibd). Не хватает table definition (data.frm).

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

create table data2 (name text, hits int(11), size int(11));

Создать таблицу с именем data не получится, так как системные таблицы всё ещё содержат её упоминание. Теперь подключим файл данных к нашей новой таблице. Для этого отключим «пустой» ibd-файл от таблицы: alter table data2 discard tablespace;, подменим его заполненным mv data.ibd data2.ibd и подключим обратно alter table data2 import tablespace;.

Так как db.data до сих пор числится в системных таблицах, то drop table db.data мы сделать не сможем. Придётся создать временную базу данных, перенести в неё новую таблицу, удалить старую, а затем создать заново:

rename table db.data2 to db2.data;
drop database db;
create database db character set utf8;
rename table db2.data to db.data;
alter table db.data engine = innodb;

Осталось лишь выдать доступ пользователю: grant all privileges on db.* to 'checker'@'%' identified by 'masterkey';. К сожалению, проверка так и не проходит из-за ошибки подключения. Проверка с помощью tcpdump показывает, что mysqld не отвечает. Проверим фаервол с помощью iptables-save и обнаружим проблему, оставленную злодеем, — в таблицу nat добавлены ошибочные правила. Однако, их удаление ненадолго восстанавливает работу сети — правила появляются снова.

Как правило, периодические действия вызваны работой crontab. Проверим (crontab -l, cat /etc/cron.* /etc/crontab /etc/cron.d/*) и удалим все задания текущего пользователя (crontab -r).

3.Binary


Run 1.exe


В данном задании нужно запустить «необычную» программу. Из задания нам известно имя файла — «1.exe». Найдём файл на файловой системе и проверим его содержимое:

# find / -iname 1.exe
/root/1/1.exe
# file /root/1/1.exe
/root/1/1.exe: PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows

Для запуска .NET-приложений под GNU/Linux существует среда mono. Установим её (pacman -S mono) и попробуем запустить нашу программу:

# cd /root/1
# mono 1.exe

Но это задание не такое простое, как кажется. В ответ, game вернёт:

Name: Binary
Status: uncompleted
Output: bad program

Попробуем понять, что же делает программа 1.exe. Запуск mono под strace покажет, что программа слушает TCP-сокет и выполняет команды, переданные проверкой. Поверхностный анализ трафика с помощью tcpdump показывает, что программа умеет читать файлы, обращаться к встроенной базе данных и выполнять вычисления. Проверка заканчивает работу после выполнения вычислений, значит, проблема скорее всего заключается в них.

Часто можно извлечь дополнительную информацию, поискав текстовые строки внутри исполняемых файлов. Попробуем воспользоваться этим приёмом — установим пакет программ binutils и применим программу strings на файл 1.exe. Один фрагмент вывода похож на список библиотек, используемых программой:

System.Core
mscorlib
System.Xml
dnAnalytics

Все эти библиотеки, кроме dnAnalytics, входят в состав mono — это несложно проверить с помощью пакетного менеджера (pacman -Ql mono).

Установим недостающую библиотеку, скачав и распаковав архив с официального сайта (bin/*.dll нужно положить в /root/1).
После перезапуска, программа успешно проходит проверку.

4.Mongo


В этом задании нужно развернуть шардированное хранилище MongoDB, записав в него данные, предложенные организаторами.

There is a database in /var/lib/db.tar.gz.

Make a root.features collection with 2 shards and make it available on the standard port.

Для начала установим mongodb: pacman -S mongodb. Организаторы оставили архив с базой, распакуем его и сделаем архивную копию:

cd /var/lib/mongodb
tar jxf /var/lib/db.tar.bz2
mongod --dbpath db
mongodump
rm -rf db

Для шардирования понадобится специальная служебная база, называемая configdb. Создадим её:

mkdir -p /data/configdb
mongod --configsvr &

Теперь запустим «шардировщик» mongos: mongos --configdb localhost &. В задании требуется поднять два шарда, поэтому подготовим два экземпляра mongod:

mkdir /var/lib/mongodb/s1 /var/lib/mongodb/s2
mongod --dbpath /var/lib/mongodb/s1 --port 30001 --nojournal &
mongod --dbpath /var/lib/mongodb/s1 --port 30002 --nojournal &

И подключим их к mongos:

# mongo
mongos> sh.addShard("localhost:30001")
mongos> sh.addShard("localhost:30002")
mongos> sh.enableSharding("root")

Теперь осталось загрузить дамп обратно: mognorestore --port 30001 dump/.

Однако этого недостаточно для решения задачи — коллекция root.features не будет равномерно расшардирована между двумя шардами. Решим эту проблему, создав индекс по идентификатору документа и включив балансировщик:

# mongo root
mongos> db.features.ensureIndex({"_id":"hashed"})
mongos> sh.shardCollection("root.features", {"_id":"hashed"})
mongos> sh.enableBalancing("root.features")

Подождав, пока коллекция перераспределится между шардами, запустим проверку повторно.

5.Strange Protocol


Это задание оказалось самым сложным. Собственно, как мы и сами предсказывали.
Set up an echo server on port 13000.

На этот раз нам нужно запустить эхо-сервер на порту 13000.

Это задание кажется простым — действительно, простейшая реализация эхо-сервера уже встроена, например, в xinetd. Запуск tcpdump port 13000 показывает, что обмен происходит по протоколу UDP, но настройка echo-dgram в xinetd не даёт ожидаемого результата.

Посмотрим на трафик внимательнее — снова запустим tcpdump, но уже с параметром -X. Последний пакет кажется интересным:

 0x0010:  0a00 000f ebee 32c8 0012 ffd6 656e 6574  ......2.....enet
 0x0020:  2065 7272 6f72                           .error

Поиск по слову enet приводит к сайту, описывающему реализацию протокола enet, который позволяет передавать потоки данных через UDP, не заботясь о потере пакетов (как в TCP).

Дальнейший поиск приводит к библиотеке pyenet, привязке к enet для языка Python, который как раз подойдёт для нашей задачи. Напишем несложную программу:

import enet
import sys

host = enet.Host(enet.Address(b'0.0.0.0', 13000), 100, 0, 0)

while True:
    evt = host.service(0)
    if evt.type == enet.EVENT_TYPE_RECEIVE:
        data = evt.packet.data
        evt.peer.send(0, enet.Packet(data))

Осталось установить эти библиотеки:

pacman -S git
git clone git://github.com/aresch/pyenet
cd pyenet
git clone git://github.com/lsalzman/enet
pacman -S cython base-devel
python setup.py build
python setup.py install

Запускаем нашу программу, и проверка на этот раз выполняется успешно.

6.File


Организаторы спрятали root.txt где-то внутри /root/file.
There is a /root/file inside your image. Find a good root.txt file and make it available via image_ip/root.txt.

Попробуем понять, чем же является /root/file:

# file /root/file 
/root/file: LVM2 PV (Linux Logical Volume Manager), UUID: XT6zLL-YAUv-nmA9-BSrw-2pBV-CTi2-vqKe35, size: 31457280

Похоже на образ диска. В Linux есть модуль ядра loop, который позволяет превращать файлы в блочные устройства. Воспользуемся им:

losetup /dev/loop0 /root/file

Так как внутри образа диска находится том LVM, подключим его штатными средствами:
# vgchange -ay
  1 logical volume(s) in volume group "VolGroup00" now active

Посмотрим, что внутри:

mount /dev/mapper/VolGroup00-lv0 /mnt
ls /mnt

Видим root.txt.gz, распаковываем: gunzip /mnt/root.txt.gz.

Так как мы уже установили nginx для задания SSL, воспользуемся им для раздачи файла по HTTP:
umount /mnt
mount /dev/mapper/VolGroup00-lv0 /usr/share/nginx/html/

К сожалению, проверка не проходит — мы нашли не тот root.txt. Будем смотреть дальше. Посмотрим, какая у нас файловая система:

# file -s /dev/dm-0
/dev/dm-0: BTRFS Filesystem sectorsize 4096, nodesize 4096, leafsize 4096)

Поскольку в btrfs есть понятние subvolume, посмотрим на их список:

# pacman -S btrfs-progs
# btrfs subvolume list /usr/share/nginx/html/
ID 256 gen 14 top level 5 path root
ID 257 gen 11 top level 5 path root_1

Оказывается, есть ещё один subvolume — root_1. Смонтируем именно его:

umount /usr/share/nginx/html
mount -t btrfs -o subvol=root_1 /dev/mapper/VolGroup00-lv0 /usr/share/nginx/html/

Теперь мы нашли другой файл root.txt.gz. Распакуем его: gunzip/usr/share/nginx/html/root.txt.gz.

Это и будет решением задачи.

7.MariaDB Tuning


Во время решения задачи MariaDB repair мы починили базу данных, но она работает слишком медленно. Настало время исправить это.

The repaired MariaDB is slow. Tune it up.

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

mysql -u root -ppassword db
mysql> set global slow_query_log = ON;
mysql> set global long_query_time = 1;

Запускаем проверку и смотрим в лог: tail /var/lib/mysql/shannon-slow.log.

Видим запрос SELECT COUNT(*) FROM db.data WHERE size < 10;.

Посмотрим на план запроса:

mysql> explain SELECT COUNT(*) FROM db.data WHERE size < 10 \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: data
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 25061163
        Extra: Using where
1 row in set (0.00 sec)

Конечно же, такой запрос выполяется слишком медленно — у нас нет индексов для этого поля. Добавим индекс: mysql> create index data_size on data(size);.

Повторный запуск проверки покажет нам ту же проблему для data(hits), которую мы решаем аналогичным образом.

8.HG


В /root/repo лежит mercurial репозиторий, для которого нам надо поправить историю и сделать его доступным через http.

There is a HG repository in /root/repo.

Drop all .gz files in all revisions and make it available via ip:8000/

Первым делом, установим mercurial: pacman -S mercurial. Изменить историю можно с помощью модуля convert, который по умолчанию отключён. Включим его:

# cat <<EOF > ~/.hgrc
[extensions]
hgext.convert=
EOF

Этот модуль умеет применять правила сопоставления файлов в исходном и целевом репозитории. Такие правила называются filemap. Напишем и применим правило, которое выкинет файл 2.osm.gz:

echo 'exclude "2.osm.gz"' > /root/fmap
hg convert --filemap ~/fmap /root/repo /root/repo1

После выполнения команды, получим репозиторий /root/repo1, который лишён файла 2.osm.gz во всех ревизиях. Осталось сделать его доступным снаружи. В mercurial есть встроенный веб-сервер, которым мы и воспользуемся:

cd /root/repo1
hg serve

9.Strange File


С этим заданием справилось самое большое количество команд — 151. На файловой системе находится странный файл tester/file, который никто не может изменить.

We got a strange file in ~tester/file. No one can change it. Fix it.

И действительно, файл изменить не получается — даже из-под рута:

# echo test >> ~tester/file
-bash: /home/tester/file: Permission denied

Для начала посмотрим, что у нас за файловая система такая:
# mount | grep ' on / '
/dev/sda2 on / type ext4 (rw,relatime,data=ordered)

Из руководства по ext4 (man 5 ext4) можно узнать, что файлы на этой ФС могут иметь
следующие атрибуты:
FILE ATTRIBUTES
The ext2, ext3, and ext4 filesystems support setting the following file attributes on
Linux systems using the chattr(1) utility:

a — append only

A — no atime updates

d — no dump

D — synchronous directory updates

i — immutable

S — synchronous updates

u — undeletable

In addition, the ext3 and ext4 filesystems support the following flag:

j — data journaling

Finally, the ext4 filesystem also supports the following flag:

e — extents format

For descriptions of these attribute flags, please refer to the chattr(1) man page.

Посмотрим на страницу chattr(1), где подробно описывается поведение системы для файлов с установленым атрибутом immutable:
ATTRIBUTES
A file with the 'i' attribute cannot be modified: it cannot be deleted or renamed, no link can be created to this file and no data can be written to the file. Only the supe‐ruser or a process possessing the CAP_LINUX_IMMUTABLE capability can set or clear this attribute.

Ответ очевиден — нужно снять этот атрибут с файла: chattr -i ~tester/file. Задача решена.
Автор: @kmeaw
Яндекс
рейтинг 361,67

Комментарии (73)

  • +14
    Задания довольно интересные, нам игра понравилась (команда Danzai!).
    Мы решили SSL куда проще, всего в 2 команды:
    openssl req -sha256 -newkey rsa:2048 -keyout serv.key -out serv.req -nodes
    openssl x509 -req -days 730 -in serv.req -CA ca.crt -CAkey ca.key -set_serial 01 -out serv.crt
    Главное не забыть поставить правильный CN. Когда сдавали задание, поле output в SSL вообще не появлялось, поэтому приходилось только догадываться, по какой причине оно не засчитывается. Все решилось правильной настройкой TLS.

    Третье задание для меня было вообще не очевидным, пришлось реверсить через рефлектор.

    Было несколько неприятных фактов:
    1. Не ответили на письмо в техподдержку. Почти все общение происходило на фейсбуке, это как вообще называется?
    2. Часто отваливался или вовсе не работал VPN. Не нужно указывать в конфиге OpenVPN параметр link-mtu 1492, минусы от уменьшения MTU этим параметром перевешивают плюсы. Я понимаю, вы хотели сделать так, чтобы у людей с PPPoE пакеты не фрагментировались, но нужно использовать mssfix и fragment для UDP (но у вас такие большие пакеты по UDP не ходили ни в одном задании, вроде). Причем, по умолчанию, mssfix настроен на 1450, т.е. TCP-пакеты не будут фрагментироваться на линках с MTU>=1450 (а это и PPPoE, и PPTP).
    3. Почту так и не починили даже к концу игры. Неправильная DKIM-запись, 9 одинаковых сообщений каждый раз, неправильный ник в уведомлениях о выполнении задания.

    Ну это так, мелочи. Игра была интересной, так держать!

    Лоровцы, вы крутые!
    • +4
      Забыл упомянуть что game начал работать только через час после начала игры.
    • 0
      Конечно, 14 человек, не то что нас — 5.
      • 0
        В ТОП-5 есть команда из 3-х человек, если что. Так что количество тут не решало.
      • 0
        Ну я в одно лицо принимал участие, так-как у команды внезапно случилась своя олимпиада на работе ;) И ничо 78 место.
    • 0
      Да, вначле были проблемы, это факт. Надо чаще играть и тренироваться нам самим!
      Про тех поддержку — видимо пропустили, а ФБ — это на текущий момент у нас, к сожелению, единственный вариант, так как my.ya.ru закрыт. Сама пользовалась в таком формате ФБ первый раз и не могу сказать, что в восторге. Если есть альтернативы — welcome!
      • +4
        Может что то админское, старый, добрый IRC?
      • –2
        Как на счет gitter.im?
  • +11
    олимпиада для Unix-инженеров и системных администраторов.

    Рискую быть заминусованным, но всё же рискну поныть.
    • Арч
    • HG
    • Btrfs

    Много ли системных администраторов имеют в продакшене эти вещи? Доходило до смешного — никто, кроме одного участника команды, не знал, как пользоваться пакетным менеджером. Еще можно пожаловаться на монгу, но она всё-таки более-менее в тренде. Кто всё-таки и для кого делал это соревнование?
    • 0
      Много ли системных администраторов имеют в продакшене эти вещи?
      R.
    • 0
      Много ли системных администраторов имеют в продакшене эти вещи?
      Еще можно пожаловаться на монгу, но она всё-таки более-менее в тренде. Кто всё-таки и для кого делал это соревнование?

      В продакшене такое едва ли можно найти, но он имеет свойство меняться, а наиболее вероятные изменения, т.е. будущие «тренды» и можно увидеть в арче — btrfs, systemd и компания.

      Доходило до смешного — никто, кроме одного участника команды, не знал, как пользоваться пакетным менеджером.
      Pacman же дубовый, если человек знаком с любым другим пакетным менеджером, то с маном разберется с ним за десяток минут.

      И встречный вопрос к вам — как часто вы встречаетесь с новыми, незнакомыми технологиями в работе? Это тоже можно считать соревновательным элементом.
      • 0
        можно увидеть в арче — btrfs, systemd и компания.
        Да что вы так конкретно в арч въелись? Будто CentOS 7 и Fedora не используют systemd и btrfs. Это, вроде, уже стандарт. Дебиан 8 выходит через пару месяцев, тоже с systemd по умолчанию.
      • 0
        В продакшене такое едва ли можно найти, но он имеет свойство меняться, а наиболее вероятные изменения, т.е. будущие «тренды» и можно увидеть в арче — btrfs, systemd и компания.

        это всё понятно, дебианы-убунты-центоси уже на системд. но тем не менее, тот же btrfs эти товарищи не впаривают.

        И встречный вопрос к вам — как часто вы встречаетесь с новыми, незнакомыми технологиями в работе? Это тоже можно считать соревновательным элементом.


        естественно, не всю жизнь апач ставлю. я с этим и не спорю.
        • 0
          тот же btrfs эти товарищи не впаривают

          В последнем обновлении Oracle Linux включили официальную поддержку для неё.
          • 0
            однако, система по-умолчанию там xfs, а не btrfs.
    • 0
      Погуглить слабо? Я arch в живую видел в первый раз в жизни.
    • +1
      Соревнование включало в себя не только проверку знания совокупности технологий, но и умение быстро разобраться в незнакомой ситуации и нагуглить решение.
    • 0
      hg только и используем в продакшне. Не понимаю гитовцев :)
      • +2
        Не понимаете Торвальдса — зачем вам Линукс? )
  • 0
    Спасибо, получилось интересно.
    С HG был хинт :) Удяляем файл, делаем коммит. Но game находит его в какой-то ревизии. Переименовываем /root/repo и создаем пустую директорию. Копируем в пустую /root/repo единственный файл 2.osm, далее:

    cd /root/repo
    hg init
    hg add 2.osm
    hg commit 
    hg serve
    
    • 0
      Соглашусь, в целом весьма интересный экспириенс, несмотря на косяки с vpn и прочими пакостями.

      Вот задание с HG нас выморозило всех больше. Участвовали с другом вдвоём, на это задание затратили 7 часов. При том, что сделали его изначально минут за 10… Вот неужели нельзя было продумать более детальный выхлоп game? Вот сказал бы он нам: «эй, слоупоки, с вашим впн и каналом с мту 900 идите-ка лесом, слишком долго реп качается и задание по таймауту провалено...». Уже где-то за час до завершения нас осенило всё-таки написать в саппорт («может косяк-то всё-таки не с нашей стороны?»). Благо в течение 40 минут получили первый ответ с запросом уточнения данных по команде и ip, далее в логах вижу движуху по HG, ещё минут через 10 ответ вида: меркуриал настроен правильно, но слишком долго занимает проверка. Благо у друга где-то у клиента стоял какой-то сервак с некоторыми ресурсами, пришлось переносить туда имидж, разворачивать его, запускать репозиторий уже там и пройти всё-таки эту проверку, но уже скатившись до 30 места. Всё было бы проще, будь нормальный output по проходимым заданиям.
      Anyway всё было интересно и забавно, несмотря на то, что постоянно дёргали по работе, не давая сосредоточиться на прохождении заданий)
  • 0
    Для тех, кто в танке, поясните, пожалуйста, что нужно делать с dnAnalytics-то этой? Качать с codeplex дллки и подсовывать куда-то там?
    • +2
      Сам контест очень понравился! Ощутил себя в шкуре семиклассника на олимпиаде по математике для старшеклассников: 4 часа стопроцентной концентрации над трудными задачами, которые никак не поддаются
    • 0
      Скачать и положить рядом с 1.exe. Все.
      • 0
        Оно после этого должно вместо Error :( что-то другое возвращать по http? Просто game уже не работает — проверить не могу
        • 0
          Там ещё и запросы правильные должны быть. Error говорит, если запрос не опознан.
        • 0
          Да, там есть две функции, которые требуют эту библиотеку. Одна комплексные числа считает, а другая в степень возводит, что ли, не помню.
  • 0
    В проведении олимпиады с захватом рабочего времени на центральной территории РФ был какой-то тайный умысел или просто недалёкий человек время выбирал?

    Это, наверное самая большая проблема.

    Арч… не знаю где мне это пригодится, но было прикольно по изучать новую для себя систему. Почему не funtoo?

    Про «Strange protocol»: конечно круто придумали, но «нормальный» администратор сначала ищет готовые, стандартные, работающие решения (если изначально не указано иное), а потом уже занимается разбором почему стандартное решение не взлетело и наконец пишет что-то.

    По «Binary»: ИМХО описанное решение уж как-то совсем не для администратора. Можно же взять тот же .NET Reflector и посмотреть, какие сборки нужны приложению, какие из них есть в установленном mono.

    По «MariaDB Tuning»: а вот тут описали красивое решение. Есть более простое «в лоб» — увеличиваем query cache. У game всего несколько вариантов запросов — в конце концов запрос отрабатывает за требуемое время ;)

    По «SSL»: прикольно конечно, что commonName надо правильное значение писать, но когда VPN рвётся и это значение меняется… Получается ну очень далёкая от реальной практики задача…
    • +2
      Соглашусь относительно времени проведения — всё-таки задания такие, над которыми стоит подумать, но и работать нужно же :)
      • +3
        я лично сказал начальству, что планирую заниматься повышением опыта путём участия в данном мероприятии, что было встречено с пониманием и одобрением.

        к слову конкурс продолжался до часа ночи, после работы вполне себе можно было поучаствовать для интереса. а если хочется чего-то большего, чем участие — будьте добры, найдите время, хоть отгул на этот день берите.
        • +2
          Так и отпустят 8 спецов из отдела, половину из которых некому замещать в один день в отгул ;)
          Если Вас так легко отпускают в любое время — видимо работы мало. Если при этом ещё хорошо платят — я Вам искренне завидую.
          • 0
            Ну у всех по-разному. У меня команда онлайновая. Один участник вообще из другого города. Все в момент проведения конкурса были на работе.
            Всё равно всем не угодишь в общем.
            • 0
              Ну у всех по-разному.

              Вот и я о том же.
              А соревнование, это когда участники в равных условиях ;)
              • 0
                Как минимум в одном часовом поясе?)
                • 0
                  При чём тут пояса?
                  Если бы хоть один отборочный сделали в выходной день.
                  • 0
                    Кто-нибудь бы ныл, что в выходные не может
                    • +1
                      1. Никто не «ноет» мы тут делимся впечатлениями и пожеланиями
                      2. Этапа отборочных то два. Один в рабочий день, другой в выходной — многим удобнее было. Это просто пожелание по организации.
                      3. Вы какой-то злой… не стоит свою злость в Интернете выплёскивать — её здесь и так хватает ;)
              • –1
                Не нравится, не участвуйте, вас никто не заставляет.
    • 0
      Query Cache мне не помог. Даже с индексом.
    • 0
      Я тупо проспал половину :) товарищ по команде мой работал до 10 вечера, но тем не менее, мы таки успели выполнить все задания :) я больше мучался с запуском виртуалки под параллелс, в итоге плюнул и поставил вмварь. Ось незнакомая, да, было интересно.
  • +2
    Очень понравилось задание про strange protocol, наша команда самая первая по времени его решила даже.
    Правда реализация на С++, с которым я лет 10 назад имел дело, но разобрался относительно быстро www.mafet.ru/strange_protocol.cpp
    Пример нашёл тут github.com/r-lyeh/moon9/tree/master/deps/io/enet/demo

    Не понравилось задание про монгодб — я не понял её философию.
    И кстати SSL делал тоже нестандартно, взял набор скриптов /usr/share/doc/openvpn/examples/easy-rsa/2.0/ стёр все, сделал ./build-ca, затем заменил сгенерённые файлы на файлы из задания и сделал ./build-key-server. Правда сначала пытался просто ./build-key делать, а ещё было не понятно, какой host вызывается по https.

    Ещё кстати я писал в ТП на тему архитектуры виртуалки, мне почему-то никто не ответил. В итоге провозился около с разворотом виртуалки, т.к. у меня не было физической тачки, чтоб поставить virtualbox, были только виртуальные. В итоге сконвертировал в формат esx и запустил там.
    • 0
      Я с SSL сделал еще проще, тупо поставил гуй xca, импортировал ca и сгенерил серт для сервера, с хостом вроде очевидно там.
  • +1
    В случае кстати с починкой MySQL можно решить по другому. Пользуемся тем что метаданные таблицы хранятся в отдельном файле. Создаем таблицу как указано. Останавливаем MySQL. Далее копируем data2.frm в data.frm ставим права на чтение запись mysql далее включаем MySQL вуаля, таблица читается. Насчет индексов по умолчанию mysql пишет в /tmp который смонтирован в tmpfs т.е. в память. По этой причине и добавлен в my.cnf исправленный строка tmpdir = '/var/tmp'. Без нее будет возникать ошибка недостаточно места для записи. Как бы про такое тоже писать надо так-как у вас получается типа, а все просто.

    Насчет ssl кстати говоря провал. Так-как правильнее было все же бы по имени сделать. К примеру привязать к имени машины. А так если у вас динамический пул ip, порвалось соединение пролюбили ssl.
    • +1
      я данные для mysql вообще при помощи percona data recovery tool выдрал :)
      • 0
        Во, я тоже перконой восстанавливал. Сначала отключал tablespace и не прокатило. Видимо не в той последовательности делал.

        Перкону с наскоку не нашел как принести pacman'ом и пришлось собирать из исходников. А там неправильный Makefile был: какую-то статическую либу пытался подключить как динамическую.
    • 0
      Странно у меня такой финт не получился
      • 0
        Проверьте права на frm файл. Обычно проблема в этом.
        • 0
          Я дропнул базу, создал таблицу заново. Загасил мускл и подпихнул ibd.
          Затем ALTER TABLE data DISCARD TABLESPACE; ALTER TABLE data IMPORT TABLESPACE;
  • –3
    И это игра? За вычетом написания своего сервера и расковыривания .net — скучно. Плюс, почему arch, а не debian?
    • +1
      Это же для администраторов. Там цель вернуть в рабочее состояние, а не заниматься написательством кода. Arch чтоб было сложнее :)
      • –3
        Именно для сисадминов скучно. Какие-то мелкие бытовые неудобства без интриги и драмы.
        • 0
          Как сказать как сказать :)
        • 0
          Мне скучно не было :) как и на прошлом соревновании, я почерпнул инфу для общего развития. После прошлого конкурса активно использую tmux, например.
  • +5
    Мне показалось, что это была олимпиада по pacman и systemd, иногда большая часть времени в выполнении заданий тратилась именно на них.
    • 0
      wut? Для pacman только и нужно было что ключи -Sy для установки пакетов. С GPG ключами (если пользовался yum/apt) тоже не проблема разобраться быстро.
      systemd лично мне нужен был только в задании с MariaDB, в остальных случаях прокатывало просто пустить демона.
      • 0
        mysqld_safe — старт, kill `cat shannon.pid` — стоп
    • +3
      Не знаю, я просто отрубил проверку подписей и не парился. С системд тоже не заморачивался, screen и хардкорный запуск. Максимум на это системное барахло потрачено 10 минут.
  • +2
    У меня для Strange protocol код получился почти один в один с предложенным в статье :) Но еще пришлось добавить `if not event: continue`

    А в Binary сервер упорно хотел узнать размер /dev/random («sz /dev/random»), на что программа резонно отвечала «Error :(» и общение с проверками прекращалось. Пришлось заменить /dev/random файликом с нулевым размером, тогда пошло дальше.
    Не знаю что я делал не так, но без этого не получилось сделать.
    • 0
      хм, очень странно, я тоже смотрел дампы, у меня ругалось на совсем другое. Может вы как-то не так запустили образ?
      • +1
        Нет, я вот на фейсбуке отписал уже: действительно разница есть запускать через mono или через wine c .net внутри. mono на «sz /dev/random» выдает 0, а wine — Error
  • +1
    Binary еще можно было по strace посмотреть, явно видно попытку загрузить библиотеку и ее отсутствие. А дальше вперед в гугл.

    Strange protocol выел больше всего мозга, Я сначала пытался проанализировать пакет и найти закономерность и только спустя часа 4 нагуглил библиотеку ENet, программить пришлось на C.

    В итоге наша команда на 22 месте. Реально был шанс на место 15-е, но Strange Protocol >_<
    • 0
      :) что 15-е, что 22-е все-равно не в десятке. Так что стоит ли так убиваться? :)
      • 0
        Та какая разница какое место?) я половину проспал, но сделал сам 7 заданий за 6 часов, коллега доделал остальные. Главное же все сделать кмк :) количество человек в командах неравное, это не футбол :)))
    • 0
      Забавно, что мы первые по самой сложной задаче) Этого я не ожидал. Да мне и задача не показалась сложной — гугл сильно помог вовремя.
  • +1
    Мне забавно было было, когда я схатился за первое задание — HG и внезапно увидел там себя
    # grep -c Self-Perfection /root/repo/2.osm
    253

    Потом хватаюсь за Mongo, а там опять какие-то геоданные с подозрительным упоминанием osm_id. Стало ещё веселее.

    Ну и вообще с удовольствием сыграли.
  • +1
    Спасибо, очень понравилось :)
    В задачке про Strange Protocol нагуглился-написался такой костыль, но не прошел проверки. Вдруг кому пригодится :)
    ncat -l 13000 --keep-open --udp --exec "/bin/cat"
    
    • 0
      Недостаточно просто пересылать 1в1 пакет обратно, надо ещё с тонкостями протокола enet ужиться.
      • 0
        Теперь я это понимаю, но когда читал задание — пошел не в ту степь, оказывается
  • 0
    Насчет производительности MongoDB:

    Сделали всё точно также, как написано в статье: первый запрос отрабатывал 11 секунд на моей машине. Тест не прошли. :(
    • 0
      А у нас с HG была похожая фигня (писал выше). Долго мучались, уже перед самым завершением развернули на другой машине в другом географически месте, и прошли. Вам сочувствую :(
  • +1
    • Для Strange Protocol в pyenet есть test_server.py, достаточно было изменить порт и запустить, самому ничего писать не потребовалось.
    • Когда делал MariaDB repair, то создал отдельную БД с таблицей и взял .frm для предоставленного .ibd чтобы не рисковать потерей времени если с discard tablespace что-то пойдет не так.
  • 0
    Есть у кого-то свободное место в команде? Создать новую не хочу, потому что не будет кого пригласить в ней :(

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

Самое читаемое Разное