Как мне настроить sshd на моем сервере так, чтобы он разрешал вход с паролем только из локальной сети?

Вопрос или проблема

У меня есть домашний сервер на NixOS, и я устал включать и отключать аутентификацию по паролю каждый раз, когда я хочу добавить SSH-ключ новой машины (я часто сбрасываю свои машины в заводские настройки…), поэтому я подумал, что разрешить SSH с помощью пароля, но только из моей локальной сети, – это хорошее компромиссное решение. Я попробовал погуглить и наткнулся на несколько источников, упоминающих Match Address, чтобы включить использование пароля только для определенных адресов, но, похоже, это не сработало для меня (он позволяет мне вводить пароль, но всегда отклоняет его).

Вот модуль, который я использую для SSH:

{
  services.openssh = {
    enable = true;
    ports = [ 22 ];
    settings = {
      PasswordAuthentication = false;
      AllowUsers = [ "user" ];
      PermitRootLogin = "no";
      UsePAM = true;
    };
    extraConfig = ''
      Match Address 192.168.0.0/24
        PasswordAuthentication yes
        ChallengeResponseAuthentication no
    '';
  };

}

Вот вывод journalctl -u sshd (когда я пытался ввести пароль 3 раза, прежде чем меня отключили):

04 окт 08:57:07 nixos sshd[27362]: Не удалось ввести пароль для пользователя с 192.168.0.107 порта 57276 ssh2
04 окт 08:57:09 nixos sshd[27362]: Не удалось ввести пароль для пользователя с 192.168.0.107 порта 57276 ssh2
04 окт 08:57:16 nixos sshd[27362]: Не удалось ввести пароль для пользователя с 192.168.0.107 порта 57276 ssh2
04 окт 08:57:16 nixos sshd[27362]: Соединение закрыто аутентифицируемым пользователем user 192.168.0.107 порт 57276 [preauth]

Вот результирующий sshd_config:

AllowUsers user
AuthorizedPrincipalsFile none
Ciphers [email protected],[email protected],[email protected],aes256-ctr,aes192-ctr,aes128-ctr
GatewayPorts no
KbdInteractiveAuthentication yes
KexAlgorithms [email protected],curve25519-sha256,[email protected],diffie-hellman-group-exchange-sha256
LogLevel INFO
Macs [email protected],[email protected],[email protected]
PasswordAuthentication no
PermitRootLogin no
PrintMotd no
StrictModes yes
UseDns no
UsePAM yes
X11Forwarding no
Banner none

AddressFamily any
Port 22

Subsystem sftp /nix/store/1m888byzaqaig6azrrfpmjdyhgfliaga-openssh-9.7p1/libexec/sftp-server

AuthorizedKeysFile %h/.ssh/authorized_keys /etc/ssh/authorized_keys.d/%u

HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

Match Address 192.168.0.0/24
  PasswordAuthentication yes
  ChallengeResponseAuthentication no

Я пробовал:

  • С UsePAM и без него
  • С ChallengeResponseAuthentication yes и без него
  • Используя 192.168.0.* вместо 192.168.0.0/24
  • С отступом и без отступа после оператора Match

Если я изменю PasswordAuthentication на true (вне extraConfig), он позволяет войти с паролем (разумно).

Кажется, оператор match работает, так как без него я даже не могу ввести пароль, но в настоящее время, хотя он позволяет мне ввести мой пароль, я каждый раз получаю “Permission denied, please try again”.

Редактирование:
Вот вывод sshd -d (по крайней мере, с момента попытки соединения).

Соединение с 192.168.0.140 порт 55201 на 192.168.0.12 порт 22 rdomain ""
debug1: Local version string SSH-2.0-OpenSSH_9.7
debug1: Remote protocol version 2.0, remote software version OpenSSH_9.8
debug1: compat_banner: match: OpenSSH_9.8 pat OpenSSH* compat 0x04000000
debug1: permanently_set_uid: 997/997 [preauth]
debug1: list_hostkey_types: rsa-sha2-512,rsa-sha2-256,ssh-ed25519 [preauth]
debug1: SSH2_MSG_KEXINIT sent [preauth]
debug1: SSH2_MSG_KEXINIT received [preauth]
debug1: kex: algorithm: [email protected] [preauth]
debug1: kex: host key algorithm: ssh-ed25519 [preauth]
debug1: kex: client->server cipher: [email protected] MAC: <implicit> compression: none [preauth]
debug1: kex: server->client cipher: [email protected] MAC: <implicit> compression: none [preauth]
debug1: expecting SSH2_MSG_KEX_ECDH_INIT [preauth]
debug1: SSH2_MSG_KEX_ECDH_INIT received [preauth]
debug1: ssh_packet_send2_wrapped: resetting send seqnr 3 [preauth]
debug1: rekey out after 4294967296 blocks [preauth]
debug1: SSH2_MSG_NEWKEYS sent [preauth]
debug1: Sending SSH2_MSG_EXT_INFO [preauth]
debug1: expecting SSH2_MSG_NEWKEYS [preauth]
debug1: ssh_packet_read_poll2: resetting read seqnr 3 [preauth]
debug1: SSH2_MSG_NEWKEYS received [preauth]
debug1: rekey in after 4294967296 blocks [preauth]
debug1: KEX done [preauth]
debug1: SSH2_MSG_EXT_INFO received [preauth]
debug1: kex_ext_info_check_ver: [email protected]=<0> [preauth]
debug1: userauth-request for user user service ssh-connection method none [preauth]
debug1: attempt 0 failures 0 [preauth]
debug1: connection from 192.168.0.140 matched 'Address 192.168.0.0/24' at line 34
debug1: kex_server_update_ext_info: Sending SSH2_MSG_EXT_INFO [preauth]
debug1: PAM: initializing for "user"
debug1: PAM: setting PAM_RHOST to "192.168.0.140"
debug1: PAM: setting PAM_TTY to "ssh"
debug1: userauth-request for user user service ssh-connection method password [preauth]
debug1: attempt 1 failures 0 [preauth]
debug1: PAM: password authentication failed for user: Authentication failure
Не удалось ввести пароль для пользователя с 192.168.0.140 порта 55201 ssh2
debug1: userauth-request for user user service ssh-connection method password [preauth]
debug1: attempt 2 failures 1 [preauth]
debug1: PAM: password authentication failed for user: Authentication failure
Не удалось ввести пароль для пользователя с 192.168.0.140 порта 55201 ssh2
debug1: userauth-request for user user service ssh-connection method password [preauth]
debug1: attempt 3 failures 2 [preauth]
debug1: PAM: password authentication failed for user: Authentication failure
Не удалось ввести пароль для пользователя с 192.168.0.140 порта 55201 ssh2
Соединение закрыто аутентифицируемым пользователем user 192.168.0.140 порт 55201 [preauth]
debug1: do_cleanup [preauth]
debug1: monitor_read_log: child log fd closed
debug1: do_cleanup
debug1: PAM: cleanup
debug1: Killing privsep child 1822891

если вы используете что-то вроде tailscale, вы можете настроить свой брандмауэр так, чтобы разрешить SSH только из этой сети, как я использую эту конфигурацию на своих компьютерах для удаленного доступа с паролем

{ config, pkgs, ... }:
{
  networking.firewall.interfaces."tailscale0".allowedTCPPorts = config.services.openssh.ports;
  services.openssh = {
    enable = true;
    openFirewall = false; # настройте так, чтобы он был доступен только в tailscale
    settings = {
      X11Forwarding = true;
      PasswordAuthentication = true;
      KbdInteractiveAuthentication = true;
    };
  };
}

Ответ или решение

Чтобы настроить SSH-сервер (sshd) на вашем сервере на NixOS так, чтобы он разрешал вход с паролем только внутри локальной сети (LAN), необходимо выполнить несколько шагов. Давайте более подробно рассмотрим процесс настройки, включая использование директивы Match Address, а также некоторые другие параметры конфигурации.

1. Общие настройки SSH

Начнем с основной конфигурации сервиса SSH. Откройте файл конфигурации, который у вас уже есть, и убедитесь, что вы установили базовые параметры:

{
  services.openssh = {
    enable = true;
    ports = [ 22 ];  
    settings = {
      PasswordAuthentication = false; // отключаем аутентификацию по паролю по умолчанию
      AllowUsers = [ "user" ]; // список разрешённых пользователей
      PermitRootLogin = "no"; // отключаем вход под root
      UsePAM = true; // включаем PAM для аутентификации
    };
    extraConfig = ''
      Match Address 192.168.0.0/24 // IP адреса вашей локальной сети
        PasswordAuthentication yes // включаем аутентификацию по паролю для LAN
        ChallengeResponseAuthentication no // отключаем интерактивную аутентификацию
      '';
  };
}

2. Проверка конфигурации

Запустите следующую команду, чтобы проверить, правильно ли составлен файл конфигурации SSH:

sshd -t

Убедитесь, что не возникает ошибок, которые могли бы помешать правильной работе сервиса.

3. Перезагрузка SSH сервиса

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

sudo systemctl restart sshd

4. Тестирование

Теперь проведите тестирование. Попробуйте подключиться к вашему серверу с использованием пароля из локальной сети и за её пределами:

  • Изнутри сети:

    ssh user@192.168.0.12

    Здесь замените 192.168.0.12 на IP-адрес вашего сервера.

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

5. Логирование и отладка

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

journalctl -u sshd

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

6. Устранение распространённых проблем

Если аутентификация по паролю по-прежнему вызывает ошибки:

  • Убедитесь, что пользователи действительно существуют в системе.

  • Проверьте, установлены ли правильные разрешения на домашнюю директорию и файл .ssh/authorized_keys:

    chmod 700 ~/
    chmod 600 ~/.ssh/authorized_keys
  • Убедитесь, что у пользователя установлен правильный пароль:

    sudo passwd user

Заключение

С вышеописанными шагами вы сможете настроить свой SSH-сервер на NixOS так, чтобы он разрешал вход с паролем только из локальной сети, повышая безопасность вашего сервера. С использованием директивы Match Address вы сможете гибко управлять доступом, что особенно полезно в условиях часто изменяющихся сетевых конфигураций, таких как у вас.

Оцените материал
Добавить комментарий

Капча загружается...