SSH к виртуальной машине KVM через хост

/run/user/1000,который, конечно, не существует до тех пор, пока пользователь #1000 не войдет в систему или явно не запустит xyr для управления пользовательскими службами -, является отвлекающим маневром. Весь механизм, который его использует, не должен быть там.

Ошибка #215 этой программы гораздо глубже, чем вы думаете. Этот файл сервисного модуля очень неверен, , как и работа самой программы . Существует много карго-культового программирования, основанного на непонимании основ сервисных единиц systemd.

  • Служебные модули не являются сценарием оболочки. Руководство по systemd объясняет это. Параметр ExecStartздесь вызывает запуск служебной программы с некоторыми дополнительными аргументами, 2>&1>и /dev/null.
  • Диспетчер служб уже обеспечивает запуск только одной службы.Весь этот код, добавленный сюда, является ненужным мусором.
  • Ненадежный и опасный файловый механизм PID следует не использовать. Ему нет места в надлежащем управлении услугами.
  • Диспетчер служб также обрабатывает вызов службы в контексте демона. Много другого кода в main()является также ненужным мусором, основанным на ошибке демонизации.
    • Программа вообще не должна fork()ing, а механизм готовности службы не должен указываться как Type=forking. Как и многие другие программы в реальном мире, эта программа не использует протокол готовности к разветвлению.
    • Программа уже запущена от имени суперпользователя. User=rootне требуется, и действительно, служба должна быть переработана так, чтобы не не требовалось запускать с привилегиями суперпользователя, а скорее запускать под эгидой выделенной непривилегированной учетной записи службы.
    • Диспетчер служб уже регистрирует стандартный вывод и ошибки и делает это лучше, чем эта программа.Эта домашняя -выращенная система ведения журналов просто увеличивает файл журнала до тех пор, пока он не заполнит всю файловую систему, потребляя все аварийное пространство, зарезервированное для суперпользователя.
    • Ваш журнал представляет собой просто стандартную ошибку, легко доступную из C++ как std::clog.
    • Фактически, весь код от fork()до перенаправления стандартной ошибки не должен использоваться. Управление службами обрабатывает все из этого, от руководства сеансом через рабочий каталог и umask до стандартного ввода-вывода, и делает это должным образом. Эта программа этого не делает и не должна пытаться сделать что-либо из этого для себя при использовании под диспетчером служб.

      Все, что вы взяли из Boost, было неверным.

  • Три единицы обслуживания — это ненужные накладные расходы на техническое обслуживание. Они отличаются только настройками After, и их можно просто объединить в один.
  • Безжалостное завершение не является успехом. Учитывая, что уже была одна проблема с очисткой файлов после завершения, SuccessExitStatus=SIGKILLзаблуждается. Нормальное завершение должно быть изящным через SIGTERM, а SIGKILLследует считать ненормальным. (Конечно, весь outputфайловый механизм представляет собой плохо реализованный доморощенный -механизм ведения журнала, который не следует использовать при управлении службами, как уже объяснялось. )Это значение по умолчанию для systemd.
  • Должны запускаться деструкторы объектов базы данных и другие вещи. Не оставляйте main()с exit().

Программа-демон, правильно реализованная для работы под менеджером служб, будь то из daemontools, runit, s6, nosh, systemd или чего-то еще, намного короче:

// the same until this point
void pvo_upload(void)
{
    std::clog << "Starting Daemon..." << std::endl;

    CommonServiceCode();

    std::clog << "Stopping Daemon..." << std::endl;
}

int main(int argc, char *argv[])
{
    int c;
    const char *config_file = "";

    /* parse commandline */
    while(1)
    {
        static struct option long_options[] =
        {
            { "config-file", required_argument, 0, 'c' },
            { 0, 0, 0, 0 }
        };

        int option_index = 0;
        c = getopt_long (argc, argv, "c:", long_options, &option_index);

        if (c == -1) break;

        switch (c)
        {
            case 'c':
                config_file = optarg;
                break;
            default:
                return EXIT_FAILURE;
                break;
        }
    }

    if (cfg.readSettings(argv[0], config_file) != Configuration::CFG_OK)
        return EXIT_FAILURE;

    std::clog << "Starting SBFspotUploadDaemon Version " << VERSION << std::endl;

    // Check if DB is accessible
    db_SQL_Base db = db_SQL_Base();
    db.open(cfg.getSqlHostname(), cfg.getSqlUsername(), cfg.getSqlPassword(), cfg.getSqlDatabase());
    if (!db.isopen())
    {
        std::clog << "Unable to open database. Check configuration." << std::endl;
        return EXIT_FAILURE;
    }

    // Check DB Version
    int schema_version = 0;
    db.get_config(SQL_SCHEMAVERSION, schema_version);
    db.close();

    if (schema_version < SQL_MINIMUM_SCHEMA_VERSION)
    {
        std::clog << "Upgrade your database to version " << SQL_MINIMUM_SCHEMA_VERSION << std::endl;
        return EXIT_FAILURE;
    }

    // Install our signal handler.
    // This responds to the service manager signalling the service to stop.
    signal(SIGTERM, handler);

    // Start daemon loop
    pvo_upload();

    return EXIT_SUCCESS;
}

И служебный блок тоже короче:

[Unit]
Description=SBFspot upload daemon
After=mysql.service mariadb.service network.target

[Service]
Type=simple
TimeoutStopSec=10
ExecStart=/usr/local/bin/sbfspot.3/SBFspotUploadDaemon
Restart=on-success

[Install]
WantedBy=multi-user.target

Вывод журнала можно просмотреть с помощью systemctl statusиjournalctl(с опцией -uи именем службы, если необходимо ).

Дополнительная литература

0
26.03.2020, 20:32
1 ответ

Так как я мог видеть входящие пакеты, я заглянул в гостевые iptables, чтобы увидеть, что происходит, и оказалось, что весь трафик сбрасывался. Добавил к нему простое правило, и теперь я могу использовать ssh, надеюсь, это поможет кому-то еще.

iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
0
19.03.2021, 02:32

Теги

Похожие вопросы