Basic NixOS setup
Любая ОС linux после установки требует базовой настройки - установки необходимых приложений, настройку базовых служб и безопасности. Обычно для таких целей я создаю текстовый файл и в него копирую базовые команды по настройке ОС и конфигурационные файлы. У каждой версии дистрибутива Linux базовая настройка системы может отличаться.
Несколько лет назад наткнулся на Linux дистрибутив NixOS с декларативным описанием конфигурации системы и функциональным менеджером пакетов nix.
Вся конфигурация NixOS описывается в конфигурационном файле /etc/nixos/configuration.nix
, в котором указывается настройки системы, устанавливаемые пакеты и сервисы. На основе этого файла производится создание конфигурации системы командой nixos-rebuild
.
Возможные практические применения дистрибутива NixOS:
- Централизованное хранение конфигурации для различных серверов, например в git репозитории.
- Централизованное управление, конфигурирование и обновление групп серверов с помощью утилиты nixops.
- Возможность полного воспроизведения состояния системы или определённого приложения на другом сервере для отладки, так как поддерживается механизм повторяющихся сборок.
- Возможность использования полностью идентичного набора приложений на различных ОС Linux c помошью пакетного менеджера nix.
К примеру, в производстве ОС NixOS используют такие компании:
-
Tumblr - используют платформу тестирования NixOS для Jetpants - инструмент автоматизации баз данных, предназначенного для управления миллиардами строк и сотнями серверов с базами данных.
https://github.com/tumblr/jetpants/tree/master/testing -
Mozilla - используют инструменты на базе nix для облегчения разработки в Firefox.
https://github.com/mozilla/nixpkgs-mozilla -
LogicBlox - используют инфраструктуру сборки (hydra), тестирования и развёртывания (nixops) на базе nix и ОС NixOS в производственной среде.
https://www.slideshare.net/RobVermaas/nixcon-berlin-2015-nix-at-logicblox -
LumiGuide - используют структурированный монорепозиторий с конфигурацией и непрерывную интеграцию с Hydra, развёртывание систем с помощью nixops.
https://www.youtube.com/watch?v=J4DgATIjx9E -
Awake Security - вся инфраструктура построена на базе nix.
https://awakesecurity.com/blog/deploy-software-easily-securely-using-nix-deploy/
https://awakesecurity.com/blog/hocker/ -
Atlassian - Atlassian Marketplace развёрнут с использованием nix.
https://twitter.com/puffnfresh/status/992012693686046720 -
Replit - переходит с использования образов docker на создание окружения с использованием инструментов nix.
https://blog.replit.com/nix
На практике покажу как установить NixOS и сделать первоначальную настройку системы. Конфигурацию сделал заранее, осталось только скопировать её в нашу систему и активировать. Ниже приведу объяснения за что отвечает каждый файл конфигурации.
Будем ставить NixOS на виртуальную машину. Т.к. я использую нестабильную ветку, то будем ставить её. Скачиваем загрузочный ISO орбраз nixos-minimal с этой страницы https://nixos.org/channels/nixos-unstable
и грузимся с него. Дополнительную информацию по установке можно взять отсюда https://nixos.org/nixos/manual/index.html#sec-installation
.
Для удобства работы запустим openssh сервис:
sudo systemctl start sshd
И зададим пароль для пользователя nixos
:
passwd nixos
Смотрим текущий IP адрес виртуальной машины и подключаемся по этому адресу по ssh под пользователем nixos
.
ip addr show
После подключения к системе проверяем какие диски у нас подключены:
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 505.7M 1 loop /nix/.ro-store
sr0 11:0 1 552M 0 rom /iso
vda 253:0 0 20G 0 disk
Создаём разделы на диске vda (в зависимости от типа виртуальной машины диски могут отличаться) и монтируем их:
sudo parted /dev/vda -- mklabel msdos
sudo parted /dev/vda -- mkpart primary linux-swap 1MiB 4GiB
sudo parted /dev/vda -- mkpart primary 4GiB 100%
sudo mkswap -L swap /dev/vda1
sudo mkfs.ext3 -L NixOS /dev/vda2
sudo swapon /dev/vda1
sudo mount /dev/vda2 /mnt
Генерируем первоначальную конфигурацию системы:
sudo nixos-generate-config --root /mnt
После выполнения команды создаются 2 файла:
/mnt/etc/nixos/configuration.nix
/mnt/etc/nixos/hardware-configuration.nix
Приведём файл конфигурации /mnt/etc/nixos/configuration.nix
к такому виду:
sudo nano /mnt/etc/nixos/configuration.nix
{ config, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
];
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
boot.loader.grub.device = "/dev/vda";
networking.hostName = "NixOS-example";
environment.systemPackages = with pkgs; [
wget vim mkpasswd
];
services.openssh.enable = true;
users.users.rebrain = {
isNormalUser = true;
uid = 51011;
group = "rebrain";
extraGroups = [ "wheel" "users" ];
};
users.groups.rebrain = {
gid = 51011;
};
system.stateVersion = "20.09";
}
И запустим установку системы:
sudo nixos-install --no-root-passwd --root /mnt
Внимание: указывая параметр --no-root-passwd
мы запрещаем вход в систему root
пользователю.
После установки системы установим пароль для нашего пользователя rebrain
, чтобы после перезагрузки системы мы смогли подключиться удалённо по ssh:
sudo nixos-enter --root /mnt -c 'passwd rebrain'
Размонтируем разделы и выключаем виртуальную машину:
sudo umount /mnt
sudo swapoff /dev/vda1
sudo shutdown -h now
Первоначальная установка завершена, приходим к базовой настройке. В настройках виртуальной машины отключаем ISO образ и загружаемся в установленную систему.
Заходим по SSH с аутентификацией по паролю, скачиваем и распаковываем архив с конфигурацией в директорию /etc/nixos
cd /tmp
wget https://git.elven.pw/Rebrain/basic-nixos/archive/master.tar.gz -O basic-nixos-config.tar.gz
tar xzf basic-nixos-config.tar.gz
sudo cp -r /tmp/basic-nixos/nix-config /etc/nixos
У нас получается такая структура конфигурации:
- основные настройки системы хранятся в директории
/etc/nixos/nix-config/generic
. - индивидуальные настройки текущего сервера в директории
/etc/nixos/nix-config/servers/example
.
Приводим конфигурацию /etc/nixos/configuration.nix
к такому виду:
sudo nano /etc/nixos/configuration.nix
{ config, pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./nix-config/servers/example/configuration.nix
];
system.stateVersion = "20.09";
}
Генерируем хеш пароля для пользователя rebrain
командой:
mkpasswd -m sha-512
И вставляем результат в /etc/nixos/nix-config/servers/example/users.nix
в hashedPassword
- _generated_hash_pass_
заменяем на хеш. В итоге конфигурация будет выглядеть так:
sudo nano /etc/nixos/nix-config/servers/example/users.nix
{ config, ... }:
let
ssh-keys = import ./../../generic/security/ssh-keys.nix;
in {
users = with ssh-keys; {
users.root = {
hashedPassword = null;
};
users.rebrain = {
isNormalUser = true;
uid = config.uid-gid.rebrain;
group = "rebrain";
extraGroups = [ "wheel" "users" ];
openssh.authorizedKeys.keys = [
work.rebrain_example
];
hashedPassword = "_generated_hash_pass_";
};
groups.rebrain = {
gid = config.uid-gid.rebrain;
};
groups.ssh-users = {
members = [ "rebrain" ];
};
};
}
Чтобы авторизоваться на сервере по ключу прописываем в файл generic/security/ssh-keys.nix
публичный ключ:
sudo nano /etc/nixos/nix-config/generic/security/ssh-keys.nix
{
work = {
rebrain_example = "_ssh_public_key_example";
};
}
Ссылка на ключ work.rebrain_example
уже прописана в файле servers/example/users.nix
:
...
users.rebrain = {
...
openssh.authorizedKeys.keys = [
work.rebrain_example
];
...
Внимание, параметр users.root = { hashedPassword = null; };
запрещает вход в систему root
пользователю.
Если необходимо управлять текущей системой c помощью утилиты nixops, то добавляем ssh ключ root
пользователю:
sudo nano /etc/nixos/nix-config/generic/security/ssh-keys.nix
{
work = {
...
root_example = "_ssh_public_key_example";
};
}
sudo nano /etc/nixos/nix-config/servers/example/users.nix
...
users.root = {
hashedPassword = null;
openssh.authorizedKeys.keys = [
work.root_example
];
};
...
Если в системе используется вместо vda
диска используется sda
, то в файле
/etc/nixos/nix-config/servers/example/configuration.nixменяем
/dev/vdaна
/dev/sda`:
sudo nano /etc/nixos/nix-config/servers/example/configuration.nix
...
boot = {
loader.grub.device = "/dev/sda";
...
Обновляем конфигурацию системы и перезагружаемся:
sudo nixos-rebuild boot
sudo shutdown -r now
При первом входе zsh предлагает сконфигурировать файл ~/.zshrc
, т.к. у нас уже готова для него конфигурация (в файле generic/shell.nix
), то пропускаем конфигурация и создаём пустой файл - вводим 0.
Для нашей конфигурации создадим git репозиторий, который, в будущем, позволит отслеживать историю обновления системы:
sudo git config --global user.email "rebrain@NixOS-example"
sudo git config --global user.name "rebrain"
cd /etc/nixos
sudo git init && sudo git add -A && sudo git commit -m "first commit"
Все команды с git выполняем от имени root
, т.к. права папки /etc/nixos
root
пользователю.
Теперь мы можем отслеживать свою конфигурацию.
Первоначальная настрока системы завершена. Пройдемся по основным настройкам:
-
generic/nix-config/core.nix
imports = [ <nixpkgs/nixos/modules/profiles/hardened.nix>
- используем защищенный профиль системы. В некоторых случаях может привести к снижению производительности.mkOverride 700
- задаёт приоритет настройкам, если указан. Например, если в конфигурацииservers/example/configuration.nix
указатьboot.kernelPackages = pkgs.linuxPackages_5_4
; то применится последний вариант.boot.kernelPackages = pkgs.linuxPackages_latest_hardened;
- указывает применять hardened ядро с патчамиhttps://github.com/anthraxx/linux-hardened
hardware.ksm
- активируем дедупликацию памяти, в некоторых случаях позволяет сэкономить ОЗУ.environment.memoryAllocator.provider = mkOverride 700 "jemalloc";
- использовать менеджер памяти Jemalloc.networking.enableIPv6.false;
- отключаем ipv6 протокол,т.к. я его не использую.networking.dhcpcd.extraConfig = "\nnoipv6rs \nnoipv6";
- отключаем ipv6 в службе DHCPD.networking.firewall.enable = false;
- отключаем файерволл iptables, вместо него используем nftables.networking.useHostResolvConf = false;
- используется в контейнерах - использоватьresolv.conf
от хостовой машины. Отключаем.networking.usePredictableInterfaceNames = false;
- возвращаем именование сетевых интерфейсов в ethX, т.к. у меня в виртуальных машинах используется идентичные интерфейсы и их количество не превышает двух.security.sudo.wheelNeedsPassword = false;
- не запрашивать каждый раз пароль перед запуском приложения от имениroot
, т.к. мы используем аутентификацию по ключам, то не вижу смысла каждый раз требовать пароль.services.journald
- ограничиваем размер журналов до 256 MiB.services.qemuGuest
- для виртуальных машин активируем QEMU Guest агент. В противном случаем в servers/custom_server/configuration.nix прописываем - services.qemuGuest.enable = false;.users.mutableUsers = false;
- запретить смену пароля. Пароль указываем вusers.users.my-username.hashedPassword
.
-
generic/nix-config/generic/overlays/default.nix
nur = import ...
- Здесь добавляем пользовательский репозиторий с программами (полный код в примере).
-
generic/programs/ssh.nix
startAgent
- активируем ssh agent.pubkeyAcceptedKeyTypes
,hostKeyAlgorithms
- используем толькоssh-ed25519
иrsa-sha2-512
ключи.kexAlgorithms
- используем KEX алгоритмcurve25519-sha256@libssh.org
.ciphers
- используем шифрchacha20-poly1305@openssh.com
.macs
- используемhmac-sha2-512-etm@openssh.com
алгоритм аутентификации кода сообщения.extraConfig
- небольшие твики ssh клиента.
-
generic/security/ssh-hosts.nix
programs.ssh.knownHosts
- указываем принудительно публичные ключи известных хостов. По IP можно так же добавить другие виртуальные машины, куда требуется доступ по ssh. Если удалённый сервер каким либо образом подменили, то ssh клиент выдаст ошибку.
-
generic/security/ssh-keys.nix
- записываем публичные ключи для ssh аутентификации. -
generic/services/fail2ban.nix
- настраиваем работу утилиты fail2ban c файерволлом nftables, добавляем какие IP адреса игнорировать. Для сервиса sshd задаём агрессивный метод сканирования. -
generic/services/syslog-ng.nix
- сохраняем логи ssh сервера в отдельный файл. -
generic/services/logrotate.nix
- настраиваем ротацию ssh логов. -
generic/services/sshd.nix
allowSFTP = true;
- включаем поддержку SFTP.forwardX11 = mkDefault false;
- запрещаем использовать проброс X11. Если требуется проброс X11 приложений, добавляем в файлservers/example/configuration.nix
строкуservices.openssh.forwardX11 = true;
.startWhenNeeded = mkDefault true;
- запускать SSH сервер только при активации запроса на порт сервиса (активация по systemd socket).permitRootLogin = mkDefault "yes";
- разрешить пользователюroot
заходить по SSH. Требуется для работы утилиты nixops. Можно отключить, если не используете nixops -"no";
.passwordAuthentication = false;
challengeResponseAuthentication = false;
- запрещаем вход по паролю.useDns = false;
- не использовать DNS серверы, при аутентификации.macs
- используемhmac-sha2-512-etm@openssh.com
алгоритм аутентификации кода сообщения.ciphers
- используем шифрchacha20-poly1305@openssh.com
.kexAlgorithms
- используем KEX алгоритмcurve25519-sha256@libssh.org
. Большинство ssh сканеров будут отваливаться, т.к. не могут подключиться по указанным алгоритмам.authorizedKeysFiles
- использовать открытые ключи авторизации из файлов, удовлетворяющих шаблону/etc/ssh/authorized_keys.d/%u
, где%u
- имя пользователя.hostKeys
- указываем использовать только rsa и ed25519 ключи.extraConfig
- небольшие твики sshd сервера.
-
generic/services/unbound.nix
- ставим локальный ДНС сервер для кэширования запросов. -
generic/ids.nix
- задаём пользователям фиксированный UID. -
generic/locale.nix
- настраиваем шрифт, кодировку, локализацию, синхронизацию с сервером времени и часовой пояс. -
generic/pkgs.nix
- устанавливаем часто используемые программы. -
generic/shell.nix
- настраиваем shell, алисы, программу nano и ZSH. -
generic/tweaks.nix
- небольшие твики системы. -
servers/example/configuration.nix
- здесь сохраняем индивидуальные настройки для текущей виртуальной машиныexample
.boot.loader.grub.device = "/dev/vda";
- загружаемся с диска /dev/vda.boot.kernelParams = [ "lockdown=confidentiality" ];
- блокируются возможности, позволяющие вносить изменения в работающее ядро из пространства пользователя и отключается функциональность, которую можно использовать для извлечения конфиденциальной информации из ядра.
-
servers/example/users.nix
- настраиваем пользователяrebrain
.hashedPassword
- указываем фиксированный хеш пароля. Опцияusers.mutableUsers = false;
позволяет запретить смену пароля из консоли.openssh.authorizedKeys.keys
- прописываем открытые публичные ssh ключи указанные вgeneric/security/ssh-keys.nix
по которым пользователь может авторизоваться на сервере.groups.ssh-users.members
- прописываем, каким пользователям разрешён вход по ssh.
-
servers/example/services/fail2ban.nix
services.fail2ban.enable
- активируем сервис fail2ban. По умолчанию сервис отключен вgeneric/services/fail2ban.nix
.services.fail2ban.jails.sshd
- активируем jail sshd.
-
servers/example/services/firefall-nft.nix
- активируем файерволл nftables, открываем 22 порт.
В итоге мы закрыли некоторые ветки атаки и подготовили шаблон, который можно использовать на других системах на базе Linux NixOS.
Теперь подробнее о Linux NixOS.
NixOS сохраняет все приложения и различные версии конфигурации системы в собственных подкаталогах директории /nix/store
. Например приложение nano
находится в директории /nix/store/17xx786q2gdvjz01hx0j8rihmm5h2m88-nano-4.9.3
и на него создаётся символьная ссылка:
ls -lah `which nano`
lrwxrwxrwx 1 root root 63 янв 1 1970 /run/current-system/sw/bin/nano -> /nix/store/17xx786q2gdvjz01hx0j8rihmm5h2m88-nano-4.9.3/bin/nano
Текущая конфигурация системы с установленными приложениями расположена в /run/current-system
, которая ссылается на подкаталог в /nix/store
ls -lah /run/current-system
lrwxrwxrwx 1 root root 97 июл 13 12:51 /run/current-system -> /nix/store/r0ly0d2k314wfkmqkbci27hldpy5bplh-nixos-system-NixOS-example-20.09pre233323.dc80d7bc4a2
При обновлении системы создаётся подкаталог с новой конфигурацией системы в директории /nix/store
и символьная ссылка /run/current-system
переключается на неё. В загрузчик grub добавляется новая запись с конфигурацией системы.
Добавим программу Node.js версии 14 - nodejs-14_x
:
sudo nano /etc/nixos/nix-config/generic/pkgs.nix
cd /etc/nixos
git diff
diff --git a/nix-config/generic/pkgs.nix b/nix-config/generic/pkgs.nix
index c1ff0d3..41e026c 100644
--- a/nix-config/generic/pkgs.nix
+++ b/nix-config/generic/pkgs.nix
@@ -27,5 +27,6 @@
ccze lnav multitail
fio inxi spectre-meltdown-checker
lego mariadb.client
+ nodejs-14_x
];
}
Сделаем коммит в нашем репозитории:
sudo git add nix-config/generic/pkgs.nix
sudo git commit -m "config: add nodejs v14 package"
Теперь запускаем обновление системы:
sudo nixos-rebuild switch
У нас установилось новое приложение и символьная ссылка /run/current-system
переключилась на новую конфигурацию:
ls -lah /run/current-system
lrwxrwxrwx 1 root root 97 июл 13 13:05 /run/current-system -> /nix/store/6vn0pwczz9blrm7759iij3k7fmjq0xb2-nixos-system-NixOS-example-20.09pre233323.dc80d7bc4a2
Обновим переменную $PATH
и проверим версию Node.js:
rehash
node --version
v14.18.0
Примерно так выглядят несколько конфигураций системы в /boot/grub/grub.cfg
:
...
menuentry "NixOS - Default" --unrestricted {
search --set=drive1 --fs-uuid 1ea2e5e9-04be-4ae1-9ac4-b7f72602ddfc
search --set=drive2 --fs-uuid 1ea2e5e9-04be-4ae1-9ac4-b7f72602ddfc
linux ($drive2)/nix/store/8rzh2pkxb4cxh68cmfk9d0kd4lylx5cd-linux-5.7.7/bzImage systemConfig=/nix/store/6vn0pwczz9blrm7759iij3k7fmjq0xb2-nixos-system-NixOS-example-20.09pre233323.dc80d7bc4a2 init=/nix/store/6vn0pwczz9blrm7759iij3k7fmjq0xb2-nixos-system-NixOS-example-20.09pre233323.dc80d7bc4a2/init slub_debug=FZP page_poison=1 page_alloc.shuffle=1 lockdown=confidentiality loglevel=4 net.ifnames=0 nohibernate nosmt pti=on kvm-intel.vmentry_l1d_flush=always apparmor=1 security=apparmor
initrd ($drive2)/nix/store/1aj37hakkbww966zk8n8x12xnlqbw839-initrd-linux-5.7.7/initrd
}
submenu "NixOS - All configurations" {
menuentry "NixOS - Configuration 4 (2020-07-13 - 20.09pre233323.dc80d7bc4a2)" {
search --set=drive1 --fs-uuid 1ea2e5e9-04be-4ae1-9ac4-b7f72602ddfc
search --set=drive2 --fs-uuid 1ea2e5e9-04be-4ae1-9ac4-b7f72602ddfc
linux ($drive2)/nix/store/8rzh2pkxb4cxh68cmfk9d0kd4lylx5cd-linux-5.7.7/bzImage systemConfig=/nix/store/6vn0pwczz9blrm7759iij3k7fmjq0xb2-nixos-system-NixOS-example-20.09pre233323.dc80d7bc4a2 init=/nix/store/6vn0pwczz9blrm7759iij3k7fmjq0xb2-nixos-system-NixOS-example-20.09pre233323.dc80d7bc4a2/init slub_debug=FZP page_poison=1 page_alloc.shuffle=1 lockdown=confidentiality loglevel=4 net.ifnames=0 nohibernate nosmt pti=on kvm-intel.vmentry_l1d_flush=always apparmor=1 security=apparmor
initrd ($drive2)/nix/store/1aj37hakkbww966zk8n8x12xnlqbw839-initrd-linux-5.7.7/initrd
}
menuentry "NixOS - Configuration 3 (2020-07-13 - 20.09pre233323.dc80d7bc4a2)" {
search --set=drive1 --fs-uuid 1ea2e5e9-04be-4ae1-9ac4-b7f72602ddfc
search --set=drive2 --fs-uuid 1ea2e5e9-04be-4ae1-9ac4-b7f72602ddfc
linux ($drive2)/nix/store/8rzh2pkxb4cxh68cmfk9d0kd4lylx5cd-linux-5.7.7/bzImage systemConfig=/nix/store/r0ly0d2k314wfkmqkbci27hldpy5bplh-nixos-system-NixOS-example-20.09pre233323.dc80d7bc4a2 init=/nix/store/r0ly0d2k314wfkmqkbci27hldpy5bplh-nixos-system-NixOS-example-20.09pre233323.dc80d7bc4a2/init slub_debug=FZP page_poison=1 page_alloc.shuffle=1 lockdown=confidentiality loglevel=4 net.ifnames=0 nohibernate nosmt pti=on kvm-intel.vmentry_l1d_flush=always apparmor=1 security=apparmor
initrd ($drive2)/nix/store/1aj37hakkbww966zk8n8x12xnlqbw839-initrd-linux-5.7.7/initrd
}
menuentry "NixOS - Configuration 2 (2020-07-13 - 20.09pre233323.dc80d7bc4a2)" {
search --set=drive1 --fs-uuid 1ea2e5e9-04be-4ae1-9ac4-b7f72602ddfc
search --set=drive2 --fs-uuid 1ea2e5e9-04be-4ae1-9ac4-b7f72602ddfc
linux ($drive2)/nix/store/8rzh2pkxb4cxh68cmfk9d0kd4lylx5cd-linux-5.7.7/bzImage systemConfig=/nix/store/6dznb8ackalph62mw6zaan0cpq0ihpfs-nixos-system-NixOS-example-20.09pre233323.dc80d7bc4a2 init=/nix/store/6dznb8ackalph62mw6zaan0cpq0ihpfs-nixos-system-NixOS-example-20.09pre233323.dc80d7bc4a2/init slub_debug=FZP page_poison=1 page_alloc.shuffle=1 lockdown=confidentiality loglevel=4 net.ifnames=0 nohibernate nosmt pti=on kvm-intel.vmentry_l1d_flush=always apparmor=1 security=apparmor
initrd ($drive2)/nix/store/1aj37hakkbww966zk8n8x12xnlqbw839-initrd-linux-5.7.7/initrd
}
menuentry "NixOS - Configuration 1 (2020-07-13 - 20.09pre233323.dc80d7bc4a2)" {
search --set=drive1 --fs-uuid 1ea2e5e9-04be-4ae1-9ac4-b7f72602ddfc
search --set=drive2 --fs-uuid 1ea2e5e9-04be-4ae1-9ac4-b7f72602ddfc
linux ($drive2)/nix/store/lhc845bkk8ilfk9xsicqhwcq3ngzay8y-linux-5.4.50/bzImage systemConfig=/nix/store/x9mf5rqwnvbkizhlvd1dcin9wgfb49x3-nixos-system-NixOS-example-20.09pre233323.dc80d7bc4a2 init=/nix/store/x9mf5rqwnvbkizhlvd1dcin9wgfb49x3-nixos-system-NixOS-example-20.09pre233323.dc80d7bc4a2/init loglevel=4
initrd ($drive2)/nix/store/8f5zvilxc6y0cy05wrc6b5wqabfhd0aq-initrd-linux-5.4.50/initrd
}
...
Параметр systemConfig
указывает какую версию конфигурации использовать для загрузки системы.
Просмотреть текущие конфигурации системы можно командой:
sudo nix-env --list-generations --profile /nix/var/nix/profiles/system
Команда выдаст примерно такой результат:
1 2020-07-13 12:08:28
2 2020-07-13 12:27:27
3 2020-07-13 12:51:09
4 2020-07-13 13:05:37 (current)
Откатимся на предыдущую конфигурацию
sudo nixos-rebuild switch --rollback
switching from generation 4 to 3
updating GRUB 2 menu...
activating the configuration...
setting up /etc...
reloading user units for rebrain...
...
setting up tmpfiles
reloading the following units: dbus.service
the following new units were started: logrotate.service
Time: 0h:00m:04s
Попробуем запустить Node.js:
node --version
node: command not found
Конфигурация системы откатилась и у нас программа Node.js не установлена.
Вернёмся к последней конфигурации:
sudo nixos-rebuild switch
Также любую версию конфигурации системы можно выбрать при запуске системы, в меню grub. Очистить старые конфигурации и освободить место на диске можно командой:
sudo nix-collect-garbage --delete-old
Давайте добавим ещё один сервис для мониторинга нашей виртуальной машины. Создаём файл nix-config/servers/example/services/netdata.nix
sudo nano /etc/nixos/nix-config/servers/example/services/netdata.nix
{
services.netdata = {
enable = true;
};
}
Добавляем его в nix-config/servers/example/configuration.nix
sudo nano /etc/nixos/nix-config/servers/example/configuration.nix
...
imports =[
...
./services/netdata.nix
./users.nix
];
...
И открываем 19999
порт в файерволле nftables для нашего сервиса:
sudo nano /etc/nixos/nix-config/servers/example/services/firefall-nft.nix
...
chain input {
type filter hook input priority 0; policy drop;
jump checks-base
iif "lo" notrack accept
ip protocol icmp icmp type { echo-request} ct state new accept
tcp dport { 22 } ct state new accept
tcp dport { 19999 } ct state new accept
}
...
Обновляем систему:
sudo nixos-rebuild switch
Сервис мониторинга активирован:
systemctl status netdata
● netdata.service - Real time performance monitoring
Loaded: loaded (/nix/store/14jbfi7018j5m75ad4j23sjg811yq26l-unit-netdata.service/netdata.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2020-07-13 13:33:31 MSK; 6min ago
Main PID: 8484
IP: 124.9K in, 775.6K out
Tasks: 34 (limit: 2373)
Memory: 43.6M
CPU: 13.842s
CGroup: /system.slice/netdata.service
├─8484 /nix/store/0z9dcqk244jb0b95flpljcbs2arg5y52-netdata-1.23.0/bin/netdata -P /run/netdata/netdata.pid -D -c /nix/store/f68ak9vl3p2a8b57ypv2cq7r80a8wigc-netdata.conf
├─8491 /nix/store/0z9dcqk244jb0b95flpljcbs2arg5y52-netdata-1.23.0/bin/netdata --special-spawn-server
├─8692 /nix/store/0z9dcqk244jb0b95flpljcbs2arg5y52-netdata-1.23.0/libexec/netdata/plugins.d/go.d.plugin 1
├─8694 /nix/store/wm8d1lz8rr3i1r9vxgx123mx7rs1r5xh-wrapped-plugins/libexec/netdata/plugins.d/apps.plugin 1
└─8697 /nix/store/0z9dcqk244jb0b95flpljcbs2arg5y52-netdata-1.23.0/libexec/netdata/plugins.d/nfacct.plugin 1
...
Открываем в браузере по 19999
порту и проверяем работу.
Делаем коммит в нашем репозитории:
sudo git add -A
sudo git commit -m "config: add netdata service"
Проверяем изменения в коммите:
git diff HEAD^1
diff --git a/nix-config/servers/example/configuration.nix b/nix-config/servers/example/configuration.nix
index da117ed..d9bf023 100644
--- a/nix-config/servers/example/configuration.nix
+++ b/nix-config/servers/example/configuration.nix
@@ -3,6 +3,7 @@
./../../core.nix
./services/fail2ban.nix
./services/firefall-nft.nix
+ ./services/netdata.nix
./users.nix
];
diff --git a/nix-config/servers/example/services/firefall-nft.nix b/nix-config/servers/example/services/firefall-nft.nix
index afbab23..f6c2648 100644
--- a/nix-config/servers/example/services/firefall-nft.nix
+++ b/nix-config/servers/example/services/firefall-nft.nix
@@ -16,6 +16,7 @@
iif "lo" notrack accept
ip protocol icmp icmp type { echo-request} ct state new accept
tcp dport { 22 } ct state new accept
+ tcp dport { 19999 } ct state new accept
}
chain output {
type filter hook output priority 0; policy accept;
diff --git a/nix-config/servers/example/services/netdata.nix b/nix-config/servers/example/services/netdata.nix
new file mode 100644
index 0000000..e8b5066
--- /dev/null
+++ b/nix-config/servers/example/services/netdata.nix
@@ -0,0 +1,5 @@
+{
+ services.netdata = {
+ enable = true;
+ };
+}
В итоге мы немного ознакомились с возможностями Linux NixOS, подготовили шаблон для развёртывания ОС, закрыли некоторые ветки атаки и добавили историю изменения конфигурации с помощью git репозитория.
Примечание: Если при обновлении системы возникает ошибка:
updating GRUB 2 menu...
failed to create initrd secrets: No such file or directory
warning: error(s) occurred while switching to the new configuration
То перед обновлением выполняем команду:
sudo rm /etc/ld-nix.so.preload
В последних изменения была ошибка, которая приводила к некорректной сборке системы из-за использования провайдера распределения памяти - environment.memoryAllocator.provider
.