Ubuntu 20.04 시스템이 있는데 SSH를 통해 로그인할 때 사용자별 systemd 인스턴스를 생성할 수 없습니다.
/var/log/auth.log
Jan 26 21:36:15 hostname sshd[4181]: pam_systemd(sshd:session): Failed to create session: No such process
systemctl에 오류가 표시됩니다.
systemctl --user
Failed to connect to bus: No such file or directory
무슨 일이 일어나고 있는지 확인하기 위해 dbus를 모니터링해 보았습니다.
method call time=1611694572.932842 sender=:1.3 -> destination=org.freedesktop.DBus serial=223 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetConnectionUnixUser
string ":1.54"
method return time=1611694572.932854 sender=org.freedesktop.DBus -> destination=:1.3 serial=42 reply_serial=223
uint32 0
method call time=1611694572.932959 sender=:1.3 -> destination=org.freedesktop.DBus serial=224 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetConnectionUnixProcessID
string ":1.54"
method return time=1611694572.932971 sender=org.freedesktop.DBus -> destination=:1.3 serial=43 reply_serial=224
uint32 4373
error time=1611694572.933461 sender=:1.3 -> destination=:1.54 error_name=System.Error.EAGAIN reply_serial=2
string "Resource temporarily unavailable"
pam을 사용하도록 sshd를 구성합니다.
sshd -T| grep pam
usepam yes
/etc/pam.d/common-session에는 관련 pam_systemd.so 항목이 있습니다.
grep systemd common-session
session optional pam_systemd.so
이 문제를 추가로 진단하는 방법에 대한 아이디어가 있습니까?
답변1
문제는 dbus 소켓이 예상 위치에 없는 것 같습니다. 어디에서 연결을 시도하는지 살펴보겠습니다.
strace -fy -e connect systemctl --user >/dev/null
connect(3<socket:[186829324]>, {sa_family=AF_UNIX, sun_path="/run/user/0/systemd/private"}, 29) = 0
사용자 ID를 가져옵니다(예: id 명령 사용). /run/user/$id/systemd/private에 사용자 ID( $id )에 해당하는 파일이 있어야 합니다. 내 루트 사용자에 대한 strace 출력에는 0이 있습니다.
소켓 파일을 생성하는 시스템 코드는 다음과 같습니다.
int bus_init_private(Manager *m) {
_cleanup_close_ int fd = -1;
union sockaddr_union sa = {
.un.sun_family = AF_UNIX
};
sd_event_source *s;
socklen_t salen;
int r;
assert(m);
if (m->private_listen_fd >= 0)
return 0;
if (MANAGER_IS_SYSTEM(m)) {
/* We want the private bus only when running as init */
if (getpid_cached() != 1)
return 0;
strcpy(sa.un.sun_path, "/run/systemd/private");
salen = SOCKADDR_UN_LEN(sa.un);
} else {
size_t left = sizeof(sa.un.sun_path);
char *p = sa.un.sun_path;
const char *e;
e = secure_getenv("XDG_RUNTIME_DIR");
if (!e) {
log_error("Failed to determine XDG_RUNTIME_DIR");
return -EHOSTDOWN;
}
left = strpcpy(&p, left, e);
left = strpcpy(&p, left, "/systemd/private");
salen = sizeof(sa.un) - left;
}
(void) mkdir_parents_label(sa.un.sun_path, 0755);
(void) unlink(sa.un.sun_path);
fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (fd < 0)
return log_error_errno(errno, "Failed to allocate private socket: %m");
r = bind(fd, &sa.sa, salen);
if (r < 0)
return log_error_errno(errno, "Failed to bind private socket: %m");
r = listen(fd, SOMAXCONN);
if (r < 0)
return log_error_errno(errno, "Failed to make private socket listening: %m");
/* Generate an inotify event in case somebody waits for this socket to appear using inotify() */
(void) touch(sa.un.sun_path);
r = sd_event_add_io(m->event, &s, fd, EPOLLIN, bus_on_connection, m);
if (r < 0)
return log_error_errno(r, "Failed to allocate event source: %m");
(void) sd_event_source_set_description(s, "bus-connection");
m->private_listen_fd = fd;
m->private_listen_event_source = s;
fd = -1;
log_debug("Successfully created private D-Bus server.");
return 0;
}
로그를 확인하여 위에 나열된 오류 중 하나라도 발생했는지 확인하세요. 소켓이 존재하지 않는 이유를 확인해보세요. 무슨 일이 일어나고 있는지 확실하지 않은 경우 systemd의 디버그 로깅을 활성화할 수 있습니다.