Перейти к содержимому
curiousdevops.com
Любопытный DevOps
  • Политика конфиденциальности
  • Политика конфиденциальности
Рубрики
Uncategorized

Запуск Nixos в производстве

Логотип Nixos, созданный Тимом Катбертсоном (@Timbertson), лицензированный в рамках CC-BY 4.0. Я переместил сому … Tagged с DevOps, Nix.

  • Автор записи Автор: Minh Nguyen (he/him)
  • Дата записи 02.08.2022

Никсос логотип Создан Тимом Катбертсоном ( @Timbertson ), лицензирован под CC-BY 4.0 Анкет

Я перенес несколько предметов из моей предыдущей инфраструктуры сайта в VPS, работающий с питанием Nixos в прошлые выходные. Что заставило меня сделать это? Было несколько причин, которые пришли на ум.

Во -первых, я вроде как работал на OpenVZ — производительность довольно обнажена по сравнению с другими вариантами. У операционных систем есть только несколько вариантов. Ubuntu 16.04 (Xenial) — это нормально для работы, но на ограниченных ресурсах вещи всегда занимали намного больше времени, чем следовало бы, будь то бег Призрак Или попытка построить этот сайт на Гэтсби.

Еще одна причина для этого заключается в том, что я не помню многих вещей, которые я сделал, настраивая сайт. Могу ли я вам сказать, что установил Сертификат ? Неа. Могу ли я произнести сотню слов аргументов компилятора, чтобы я был составлен nginx с PageSpeed поддерживать? Неа. Я узнаю, как обновить PHP с 7.2, как только он достигнет Конец жизни ? Нет, мне придется посмотреть это (и мне уже нужно сделать это в своей повседневной работе!).

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

  1. Я хотел узнать больше о NIXOS и о том, как работать посредством развертывания и управления приложениями, чтобы увидеть, как оно связано с другими методами.
  2. Идея объявления конфигурации моей системы как код, который я мог бы развернуть, была для меня интересной, поскольку я трачу много времени на выполнение установки и конфигурации пакетов в свой повседневной вещи.

Некоторые детали

Для некоторого контекста я установил NIX на мою систему Arch Linux (есть полезное руководство для установки на их Wiki ). Оттуда это было вопросом создания нескольких частей конфигурации. Сам сценарий сборки оснащен Эликсиром — в основном результатом того факта, что я не мог получить сценарий Хаскелла в руководстве, которым я следил за работе.

VPS — это экземпляр Amazon EC2, который был создан с использованием Инструкции, предоставленные NIXOS Чтобы запустить предоставленное изображение Amazon Machine (AMI).

Первая остановка — Server.nix , который построен так:

let
  nixos = import  {
    configuration = import ./configuration.nix;
  };
in
  nixos.system

configuration.nix Содержит основную часть конфигурации, которая настраивается в системе:

{config, pkgs, ...}:
let
  unstable = import  {};
in
{
  imports = [ ./users.nix ./firewall.nix ./webserver.nix];
  ec2.hvm = true;
  networking.hostName = "mnguyen-nix-demo";
  environment.systemPackages = [
    unstable.caddy2
    pkgs.fish
    pkgs.htop
    pkgs.mosh
    pkgs.vim
  ];

  programs.fish.enable = true;

  # sudo without requiring password
  security.sudo.wheelNeedsPassword = false;

  ## Enable BBR module
  boot.kernelModules = ["tcp_bbr"];

  ## Network hardening and performance
  boot.kernel.sysctl = {
    # Disable magic SysRq key
    "kernel.sysrq" = 0;
    # Ignore ICMP broadcasts to avoid participating in Smurf attacks
    "net.ipv4.icmp_echo_ignore_broadcasts" = 1;
    # Ignore bad ICMP errors
    "net.ipv4.icmp_ignore_bogus_error_responses" = 1;
    # Reverse-path filter for spoof protection
    "net.ipv4.conf.default.rp_filter" = 1;
    "net.ipv4.conf.all.rp_filter" = 1;
    # SYN flood protection
    "net.ipv4.tcp_syncookies" = 1;
    # Do not accept ICMP redirects (prevent MITM attacks)
    "net.ipv4.conf.all.accept_redirects" = 0;
    "net.ipv4.conf.default.accept_redirects" = 0;
    "net.ipv4.conf.all.secure_redirects" = 0;
    "net.ipv4.conf.default.secure_redirects" = 0;
    "net.ipv6.conf.all.accept_redirects" = 0;
    "net.ipv6.conf.default.accept_redirects" = 0;
    # Do not send ICMP redirects (we are not a router)
    "net.ipv4.conf.all.send_redirects" = 0;
    # Do not accept IP source route packets (we are not a router)
    "net.ipv4.conf.all.accept_source_route" = 0;
    "net.ipv6.conf.all.accept_source_route" = 0;
    # Protect against tcp time-wait assassination hazards
    "net.ipv4.tcp_rfc1337" = 1;
    # TCP Fast Open (TFO)
    "net.ipv4.tcp_fastopen" = 3;
    ## Bufferbloat mitigations
    # Requires >= 4.9 & kernel module
    "net.ipv4.tcp_congestion_control" = "bbr";
    # Requires >= 4.19
    "net.core.default_qdisc" = "cake";
  };

  # disable passwordless SSH
  services.openssh.passwordAuthentication = false;

  # Let trusted users upload unsigned packages
  nix.trustedUsers = ["@wheel"];

  # Clean up packages after a while
  nix.gc = {
    automatic = true;
    dates = "weekly UTC";
  };

  # Disable reinitialisation of AMI on restart or power cycle
  systemd.services.amazon-init.enable = false;

  swapDevices = [
    {
      device = "/swapfile";
      priority = 10;
      size = 1024;
    }
  ];

  systemd.services.fathom = {
    description = "Fathom Server";
    requires = ["network.target"];
    after = ["network.target"];
    wantedBy = ["multi-user.target"];

    serviceConfig = {
      Type = "simple";
      User = "minh";
      Restart = "on-failure";
      RestartSec = 3;
      WorkingDirectory = "/var/lib/fathom";
      ExecStart = "/home/minh/bin/fathom --config=/etc/fathom.env server";
    };
  };
}

Импорт Притягивает конкретную конфигурацию NIXOS для EC2, на которой он работает, и я начал работать отделение конфигурации для отдельных файлов, ./users.nix , ./firewall.nix и ./webserver.nix .

Пакеты

Вы можете увидеть возле вершины configuration.nix Есть переменная, называемая Environment.systempackages Анкет В этом перечислены все дополнительные программные пакеты, которые я хочу установить. В этом случае у меня есть рыбы , HTOP , мош и Vim Установлено из стандартного репо, а также Caddy 2 Из нестабильной ветви Никсоса.

Менять

У меня нет никакого обмена на систему, поэтому переменная Swapdevices установлен для создания файла обмена в /Swapfile . Размер определяется в мегабайтах, поэтому этот файл имеет 1 гигабайт по размеру.

Брандмауэр

Никсос поставляется с настройкой брандмауэра из коробки, чтобы быть открытым только для SSH на порту 22. Чтобы изменить это, мы можем установить Networking.firewall.allowedtcpports Как список портов, мы хотим быть открытым.

Я также хочу переместить порт SSH по умолчанию на что -то другое, это определяется services.openssh.listenaddresses .

В конце концов, мой Брандмауэр. NIX Файл выглядит так:

{ config, pkgs, ...}:
{
  # SSHD Port reassignment
  services.openssh.listenAddresses = [
    { addr = "0.0.0.0"; port = 37586; }
  ];

  # Allowed TCP range
  networking.firewall.allowedTCPPorts = [80 443 37586];

  # Allow Mosh connections
  networking.firewall.allowedUDPPortRanges = [{ from = 60000; to = 60010; }];
}

Caddy Server

Двигаясь дальше, я настроил веб -сервер внутри webserver.nix :

{config, pkgs, ...}:
let
  unstable = import  {};
  caddyDir = "/var/lib/caddy";
  caddyConfig = pkgs.writeText "Caddyfile"
    ''{
  storage file_system {
    root /var/lib/caddy
  }
}
mnguyen.io {
  root * /srv/www/mnguyen.io
  file_server
  header / {
    X-Content-Type-Options "nosniff"
    X-Frame-Options "sameorigin"
    Referrer-Policy "no-referrer-when-downgrade"
    X-UA-Compatible "IE=edge,chrome=1"
    X-XSS-Protection "1; mode=block"
    Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
    Content-Security-Policy "default-src 'self'; connect-src https://analytics.mnguyen.io 'self'; font-src 'self' data:; img-src https://analytics.mnguyen.io 'self' data:; script-src https://analytics.mnguyen.io 'self' 'unsafe-inline'; style-src 'unsafe-inline'; worker-src 'self'; prefetch-src 'self'; report-uri https://mnguyen.report-uri.com/r/d/csp/enforce; report-to https://mnguyen.report-uri.com/r/d/csp/enforce"
  }
}

www.mnguyen.io {
  redir https://mnguyen.io{uri}
}

analytics.mnguyen.io {
  reverse_proxy localhost:9000
}
'';
in
{
  systemd.services.caddy = {
    description = "Caddy web server";
    after = ["network-online.target"];
    wants = ["network-online.target"];
    wantedBy = ["multi-user.target"];
    serviceConfig = {
      User = "caddy";
      Group = "caddy";
      ExecStart = ''
        ${unstable.caddy2}/bin/caddy run --config ${caddyConfig} --adapter caddyfile
      '';
      ExecReload = ''
        ${unstable.caddy2}/bin/caddy reload --config ${caddyConfig} --adapter caddyfile
      '';
      TimeoutStopSec = "5s";
      LimitNOFILE = 1048576;
      LimitNPROC = 512;
      PrivateTmp = true;
      ProtectSystem = "full";
      AmbientCapabilities = "cap_net_bind_service";
    };
  };

  users.users.caddy = {
    group = "caddy";
    uid = config.ids.uids.caddy;
    home = caddyDir;
    createHome = true;
    extraGroups = ["users"];
  };

  users.groups.caddy.gid = config.ids.uids.caddy;
}

Что это делает, это настроение Caddyfile Этот Caddy 2 будет использовать, а также служба Systemd, которая устанавливает команду, устанавливает возможности службы, чтобы она мог работать на более низких номерах портов (точнее 1024) и устанавливает выделенное Caddy Пользователь, которому он будет работать.

Пользователи

Говоря об этом, пользователи в Nixos могут быть определены в нескольких строках. Это то, что может войти в users.nix :

{ config, pkgs, ...}:
{
  users.users.minh = {
    isNormalUser = true;
    extraGroups = ["wheel"];
    shell = pkgs.fish;

    # password = "my secure password";
    # hashedPassword = "$6$qTK.7QsrnONOr$ZsAfPlnEPLtpiO9j1qp/POkDga2LtK1UOD0nrG497CegYEq5e.E6iHf5tDqwfLViBSWEsw8sn5t885p6HyRgS1";

    openssh.authorizedKeys.keys = [
      "ssh-rsa PUBLICKEYHERE"
    ];
  };
}

Флаг ISNORMALUSER сообщает Никсосу дать нам домашний каталог по адресу /дом/мин . Я тогда настроил Sudo Доступ, добавив этого пользователя в Колесо Group, установите оболочку на рыбу и установите разрешенный ключ SSH, который разрешен для доступа к этому пользователю в системе — я не могу войти в систему с паролем, если он не установлен явно.

Если бы я хотел установить пароль, я мог бы использовать небезопасную опцию пароль которая является строкой или немного более безопасной пароль (который использует хэш, сгенерированный из команды mkpasswd -М SHA-512 , подробно описано на Страница параметров пароля )

Fathom Analytics

Я вытащил последний публичный доступный выпуск Fathom Lite от их репозитория и создал файл SystemD Service для его запуска. Я немного волновался, что это не будет работать, так как на форумах сообщества было много дискуссий о том, как иметь Чтобы исправить или подражать стандартной системе Linux, чтобы двойные работы работали Анкет

К счастью, Fathom не является одной из тех программ, и это сработало безупречно без какой -либо другой работы. Он не упакован для Nixos, так что это, вероятно, наименьшая часть этой системы.

Строительство Никсоса

Есть 2 команды для создания наших пакетов Nixos и отправки их в нашу удаленную систему, а затем есть 2 другие команды для переключения профилей и активации нашей новой настройки:

  1. nix-build : которые создают пакеты Nixos
  2. nix-copy-cloulure : отправляет пакеты Nixos в наш пульт дистанционного управления
  3. nix-env : Установите профиль NIX на наши загруженные пакеты
  4. Переключатель к конфигурации : Переключить конфигурацию системы на нашу новую конфигурацию

Все они объединяются в сценарии эликсира:

server_raw = File.read!("server_address.txt")
server_processed = String.replace(server_raw, "\n", "")

defmodule Build do
  def upload_to_system(path, address) do
    {path_str, _status} = path
    fixed_path_str = String.replace(path_str, "\n", "")
    System.cmd("nix-copy-closure", ["--to", "--use-substitutes", address, fixed_path_str])
    Build.activate_nix(path_str, address)
  end

  def activate_nix(path, address) do
    profile = "/nix/var/nix/profiles/system"
    System.cmd("ssh", ["#{address}", "sudo nix-env --profile #{profile} --set #{path}"])
    System.cmd("ssh", ["#{address}", "sudo #{profile}/bin/switch-to-configuration switch"])
  end
end

System.cmd("nix-build", ["server.nix", "--no-out-link"])
  |> Build.upload_to_system(server_processed)

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

Заключительные замечания

Я немного узнал о Никсосе, но, как и большинство вещей, связано с небольшим количеством проб и ошибок. К счастью, наличие такого рода конфигурации означает, что я могу легко восстановить систему (например, когда я обнаружил, что не могу подключиться через SSH, когда я менял порт, но не осознавал, что брандмауэр также должен быть изменен).

Если вы заинтересованы в Никсосе, я бы посоветовал вам взглянуть.

Полезные ссылки

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

  • Развертывание NIXOS в Amazon EC2 По классам типа: это было очень полезно, начиная с понимания, как строить Nixos локально и как отправить его в другую установку.
  • Запуск локального DNS и веб -сервера Хосе Луис Лафуэнте: я нашел раздел для определения пользовательской службы Systemd очень полезно (просто голова, которую вы хотите установить Для пользователя в этой конфигурации в каталоге данных Caddy — Mine был /var/lib/caddy )

Оригинал: «https://dev.to/contradicthelaw/running-nixos-in-production-2nj5»

  • Метки configuration, logo, nixos, production

← Как построить конвейер регистрации для Nginx Server → DevOps Tools, которые должен знать каждый инженер

© 2026 curiousdevops.com

Политика конфиденциальности

Сайт работает на WordPress

Наверх ↑ Вверх ↑