Вопрос или проблема
У меня есть домашний сервер на 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
вы сможете гибко управлять доступом, что особенно полезно в условиях часто изменяющихся сетевых конфигураций, таких как у вас.