Развертывание ноды Ethereum
matrix
В статье рассмотрим процесс развертывания ноды Ethereum для функционирования в production и development окружении.
Рассмотрим следующие аспекты:
1) Установка с проверкой контрольной суммы
2) Конфигурация geth
3) Запуск в режиме демона
4) Защита ноды с помощью HTTPS и basic auth
5) Мониторинг ноды в jabber
Будем использовать следующие технологии:
- Debian 10.10 (https://www.debian.org)
- Geth (он же go-ethereum) 1.10.8 (https://github.com/ethereum/go-ethereum)
- Nginx 1.14.2 (https://nginx.org/ru/)
- GnuPG 2.2.12 (https://gnupg.org)
- Python 3.7 (https://www.python.org)
- sendxmpp 1.24 (https://sendxmpp.hostname.sk)
Установка Geth
Выбираем версию для скачивания go-ethereum. Эти параметры мы берем с https://geth.ethereum.org/downloads/:
VERSION="1.10.8" COMMIT="26675454" OS="linux" ARCH="amd64"
Укажем также сервер ключей для проверки подписи:
KEYSERVER="hkp://keyserver.ubuntu.com"
Скачиваем архив:
wget "https://gethstore.blob.core.windows.net/builds/geth-$OS-$ARCH-$VERSION-$COMMIT.tar.gz"
Скачиваем файл с цифровой подписью:
wget "https://gethstore.blob.core.windows.net/builds/geth-$OS-$ARCH-$VERSION-$COMMIT.tar.gz.asc"
Импортируем ключи для проверки цифровой подписи (при обновлении можно пропустить этот шаг):
gpg --keyserver "$KEYSERVER" --recv-keys F9585DE6 C2FF8BBF 9BA28146 7B9E2481 D2A67EAC
Проверяем цифровую подпись архива:
gpg --verify "geth-$OS-$ARCH-$VERSION-$COMMIT.tar.gz.asc"
Проверка успешна, если в выводе команды содержится текст:
Good signature from "Go Ethereum Linux Builder <geth-ci@ethereum.org>"
Теперь мы можем распаковать архив и скопировать исполняемый файл в /bin:
tar xzvf "geth-$OS-$ARCH-$VERSION-$COMMIT.tar.gz" sudo cp "geth-$OS-$ARCH-$VERSION-$COMMIT/geth" /bin
Настройка Geth
Создадим группу и пользователя geth для запуска демона:
sudo groupadd -r geth sudo useradd -r -g geth -m -d /data -s /sbin/nologin -c "Geth (Go Ethereum)" geth
Мы указываем ключи конфигурации Geth в файле /etc/geth/daemon_args.
Создадим каталог для конфигурации geth:
sudo mkdir /etc/geth
Строку ниже необходимо скопировать в файл /etc/geth/daemon_args:
GETH_DAEMON_OPTS='--syncmode light --datadir "/data" --http'
Такого набора ключей достаточно для запуска ноды с минимальным функционалом и запущенным локально HTTP сервером. Разумеется, в разных проектах разные требования к функционалу ноды Ethereum. Например, если требуется принимать соединения с внешних узлов через nginx (см. ниже), то следует добавить ключ --http.vhosts "example.com".
sudo chmod 700 /etc/geth sudo chmod 600 /etc/geth/* sudo chown geth:geth -R /etc/geth
Для более детальной настройки ноды Geth следует ознакомиться с выводом команды:
geth --help
Запуск Geth
Мы запускаем Geth в режиме демона. Unit-файл приведен ниже. Его необходимо положить в /usr/lib/systemd/system/geth.service
[Unit]
Description=Go Ethereum
After=syslog.target network.target
[Service]
Type=simple
EnvironmentFile=/etc/geth/daemon_args
ExecStart=/bin/bash -c "/usr/bin/geth \${GETH_DAEMON_OPTS} 2>> /data/geth.log"
PIDFile=/var/run/geth.pid
User=geth
Group=geth
Restart=on-failure
PrivateTmp=True
TimeoutStopSec=60
TimeoutStartSec=30
StartLimitInterval=120
StartLimitBurst=5
[Install]
WantedBy=multi-user.target
Теперь можно запускать демон с помощью systemctl:
sudo systemctl start geth
Остановка демона:
sudo systemctl stop geth
Логи демона хранятся в файле /data/geth.log.
Для подключения к ноде эфира можно воспользоваться командой:
sudo geth -datadir "/data" attach
Документация по командам консоли Geth: https://web3js.readthedocs.io/en/v1.2.9/
Настройка Nginx
Мы запускаем Geth локально и используем Nginx в режиме reverse proxy для реализации HTTPS и аутентификации пользователей API Geth.
Создадим пользователя и пароль API (потребуется установить пакет apache2-utils).
sudo htpasswd -c /etc/nginx/default.htpasswd api
Настройки аутентификации положим в файл /etc/nginx/snippets/basic.conf:
auth_basic "Password protected location"; auth_basic_user_file /etc/nginx/default.htpasswd;
Настройка HTTPS несколько отличается для development и production окружения. Для тестовых нод достаточно self-signed сертификата, для production-нод обычно требуется более сложная настройка в зависимости от действующих политик безопасности.
Создадим сертификат. Ответы на вопросы могут быть любыми, за исключением CN (Common name): он должен соответствовать FQDN (полному домену), или IP ноды.
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/geth.key -out /etc/ssl/certs/geth.pem
Создадим файл с параметрами протокола Диффи-Хеллмана:
openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Содержимое файла /etc/nginx/snippets/self-signed.conf:
ssl_certificate /etc/ssl/certs/geth.pem; ssl_certificate_key /etc/ssl/private/geth.key;
Содержимое файла /etc/nginx/snippets/ssl-params.conf
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; ssl_ecdh_curve secp384r1; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_stapling off; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; ssl_dhparam /etc/ssl/certs/dhparam.pem;
Содержимое файла /etc/nginx/sites-available/default:
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name _;
location / {
proxy_pass http://127.0.0.1:8545;
}
include snippets/self-signed.conf;
include snippets/ssl-params.conf;
include snippets/basic.conf;
}
После внесения изменений следует перезапустить nginx:
systemctl restart nginx
На клиенте необходимо добавить сертификат (содержимое файла /etc/ssl/certs/geth.pem на сервере). Процедура незначительно отличается в разных операционных системах. В Debian сертификат необходимо сохранить в файл /usr/local/share/ca-certificates/geth.crt и выполнить:
update-ca-certificates
Мониторинг ноды
Для обеспечения бесперебойной работы ноды Ethereum, необходимо реализовать систему мониторинга.
Крупные проекты обычно используют централизованные системы мониторинга, например, Zabbix. В этом случае мониторинг Ethereum должен осуществляться теми же средствами.
В небольших проектах может оказаться избыточным внедрение Zabbix для мониторинга. В этом случае можно воспользоваться предложенным ниже скриптом.
Скрипт необходимо сохранить под именем /usr/bin/gethmon.sh.
#!/bin/bash
LAST=`geth -datadir "/data" attach --exec "web3.eth.getBlock(web3.eth.blockNumber).timestamp"`
STATUS=$?
if (( STATUS != 0 ))
then
. /etc/geth/jabber.conf && echo "Wake up! Check the Geth node! Can't connect to the server!" | /usr/bin/sendxmpp -t -u $XMPP_USER -p $XMPP_PASSWORD -j $XMPP_SERVER $XMPP_ADM_JID > /dev/null 2> /dev/null
else
NOW=`date +%s`
DELTA=`expr $NOW - $LAST`
if (( DELTA > GETH_TIMEOUT ))
then
. /etc/geth/jabber.conf && echo "Wake up! Check the Geth node! No new blocks!" | /usr/bin/sendxmpp -t -u $XMPP_USER -p $XMPP_PASSWORD -j $XMPP_SERVER $XMPP_ADM_JID > /dev/null 2> /dev/null
fi
fi
Необходимо сделать скрипт исполняемым:
sudo chown geth:geth /usr/bin/gethmon.sh sudo chmod +x /usr/bin/gethmon.sh
Настройки скрипта необходимо положить в файл /etc/geth/jabber.conf:
XMPP_USER, XMPP_PASSWORD, XMPP_SERVER – данные Jabber-бота.
XMPP_ADM_JID – JID администратора, который будет получать уведомления.
GETH_TIMEOUT – через сколько секунд тишины ругаться.
XMPP_USER="geth_monitoring" XMPP_PASSWORD="supersecret" XMPP_SERVER="jabber.hot-chilli.net" XMPP_ADM_JID="admin@borody.net" GETH_TIMEOUT=60
Не забываем про права:
sudo chmod 600 /etc/geth/jabber.conf sudo chown geth:geth /etc/geth/jabber.conf
Теперь необходимо добавить запуск скрипта мониторинга в cron от имени пользователя geth:
echo "* * * * * /usr/bin/gethmon.sh" > crontab sudo crontab -u geth crontab
МАТРИЦА (https://t.me/matrixleaks)