Следующая новость
Предыдущая новость

Почти single sign on. Используем системную аутентификацию с сокетами UNIX

02.08.2019 13:12

Содержание статьи

  • Абстрактные сокеты Linux
  • Пишем сервер
  • Добавляем авторизацию
  • Получаем информацию о группах
  • Переносимость

Никто не любит лишний раз вводить пароли. В мире веб-приложений протоколы для SSO (Single Sign-On) широко распространены и легко реализуемы благодаря встроенной в браузер возможности хранить cookie. Со стороны безопасности это не лучшее решение. Ряд популярных приложений, к примеру консольный клиент PostgreSQL (psql), предоставляют такую возможность для локальных подключений через сокеты UNIX. В этой статье мы рассмотрим, как это сделать с помощью опции SO_PEERCRED.

В качестве примера мы напишем сервер, который просто хранит какое-то число, при этом пользователи из группы wheel могут его изменять, а все остальные — только получать значение. Писать будем на Python, но все сказанное применимо к любому языку.

В этой статье речь идет о Linux, если не указано обратное.

Абстрактные сокеты Linux

Для взаимодействия с сервером мы будем использовать вариант UNIX domain sockets — abstract namespace sockets. В отличие от сетевых сокетов, в случае с локальными сокетами UNIX ядро знает, какой процесс подключается к сокету, и знает все о пользователе (создателе) процесса, что и позволяет переиспользовать системную аутентификацию.

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

Основной недостаток классической реализации — опция SO_REUSEADDR для них не работает. Файл сокета должен быть создан процессом, который на нем слушает. Если процесс упал, а файл сокета остался, то новому процессу сначала нужно его удалить. Правильно написанный сервер должен использовать lock-файлы, чтобы предотвратить случайный запуск нескольких экземпляров процесса и обеспечить безопасное удаление старого файла.

Для решения этой проблемы в Linux существуют так называемые abstract namespace sockets. По своей сути они идентичны традиционным сокетам UNIX, но не являются файлами и автоматически исчезают с завершением процесса, который их создал. К ним также неприменимы обычные права доступа, и авторизация остается на совести приложения — но мы ведь к этому и стремимся.

Чтобы создать абстрактный сокет, нужно добавить в начало его «пути к файлу» нулевой байт. В остальном все так же, как с обычными.

Пишем сервер

Для начала мы напишем основу для сервера, пока без авторизации. Чтобы не писать разбор сообщений, мы сделаем всего две команды без аргументов: read (вернуть значение счетчика) и inc (увеличить счетчик на единицу).

Сокет мы назовем counter-server. Соответственно, путь его будет 'counter-server'.

#!/usr/bin/env python3  import os import socket  SOCK_FILE = 'counter-server'  ## Счетчик counter = 0  ## Создаем сокет sock = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM) sock.bind(SOCK_FILE) sock.listen()  while True:     conn, _ = sock.accept()      command = conn.recv(1024).decode().strip()      if command == 'inc':         print("Received an increment request")         counter += 1         response = "Success"     elif command == 'read':         print("Received a read request")         response = "Counter value: {0}".format(counter)     else:     response = "Invalid command"      conn.send(response.encode())     conn.send(b'n')     conn.close() 

Попробуем запустить его:

$ sudo ./counter-server.py  Counter server started 

Перейдем в другую консоль и попробуем подключиться с помощью socat. В случае с обычным stream-сокетом протокол был бы UNIX-CONNECT, но поскольку наш — «необычный», нужен ABSTRACT-CONNECT.

$ socat - ABSTRACT-CONNECT:counter-server  inc Success  $ socat - ABSTRACT-CONNECT:counter-server  read Counter value: 1 

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», увеличит личную накопительную скидку и позволит накапливать профессиональный рейтинг Xakep Score! Подробнее

1 год

7690 р.

1 месяц

720 р.

Я уже участник «Xakep.ru»

Источник

Последние новости