Маска — большая часть головоломки. У рута другой umask. Это довольно типично.
Часть головоломки, которую вы упускаете из виду, заключается в том, что umask — это маска. Когда приложение создает файл, оно указывает некоторые разрешения; umask — это фильтр для этих разрешений, который удаляет некоторые биты разрешений. В файле есть только биты разрешений, включенные приложением. Например, приложение, которое намеревается создать неисполняемый файл (такой как touch
), передает биты разрешения 666 (в восьмеричном формате); с umask 002 это приводит к разрешениям 664, то есть rw-rw-r--: umask удалил бит записи-другого. При создании каталога приложение (например, mkdir
) обычно разрешает выполнение и поэтому указывает 777 в качестве разрешений; umask 002 приводит к разрешениям 775 на каталог, то есть rwxrwxr-x.
Вы можете увидеть, какие разрешения использует приложение, наблюдая за системными вызовами, которые оно делает. Например:
$ strace -e open,mkdir touch foo
… skipping opening of dynamically linked libraries etc. …
open("foo", O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666) = 3
+++ exited with 0 +++
$ strace -e open,mkdir mkdir goo
… skipping opening of dynamically linked libraries etc. …
mkdir("goo", 0777) = 0
+++ exited with 0 +++
Недавно я был в такой же ситуации в Linux (виновником был adb
). Мой подход состоял в том, чтобы использовать систему аудита для регистрации системных вызовов connect()
.
sudo auditctl -a exit,always -F arch=b64 -S connect -k who-connects
Чтобы указать системе аудита регистрировать все connect()
системные вызовы (здесь 64-битный вариант, вы можете добавить еще один для 32-битных вариантов, если вы работаете в мультиархивной системе с обоими 32- и 64-разрядные приложения)
Последующий запуск:
sudo ausearch -i -k who-connects
Чтобы посмотреть, какие соединения установлены.
По-прежнему можно устанавливать TCP-соединения без использования API сокетов. Например, путем реализации стека TCP в пользовательском пространстве и использования API более низкого уровня для отправки пакетов, но это не будет обычным явлением (особенно на интерфейсе обратной связи).
Вы можете использовать команду netstat. Он показывает состояние пакета. Но вы должны поймать вывод, потому что он появляется только во время отправки. Это не похоже на прослушивающий сокет TCP. Вот почему вы можете поймать его с помощью команды watch. Предполагаю, что соединение идет по ipv4.
watch -n 0.1 'netstat -4pn | grep -F "SYN_SENT"'
флаги nestat
флаг p: идентификатор/имя процесса
флаг n: числовой вывод (без разрешения dns)
флаг 4: показать сокеты ipv4
команда watch заставляет команду netstat повторяться с интервалом в 0,1 секунды период.
Предполагая, что у вас установлен SystemTap
probe begin {
printf("ok\n");
}
probe syscall.connect {
# connect however may fail or flail around in a EINPROGRESS state;
# this log only indicates that a connect was attempted
if (uaddr_af == "AF_INET" || uaddr_af == "AF_INET6")
printf("%s[%d]: %s\n", execname(), pid(), argstr);
}
probe syscall.connect.return {
printf(" -> %s[%d]: %s\n", execname(), pid(), retstr);
}
, сохраненный как whomakeconnect.stp
будет показывать вызовы connect
при запуске с stap
как корень
# stap-prep
... fix anything reported, it requires debug kernels ...
# stap whomakeconnect.stp