1. Введение.
Итак изначальной задачей была - настройка файлового сервера Samba как файлового сервера с большим количеством пользователей, перекрестным доступом к файлам по VPN с аутентификацией через ip-адрес (тк OpenVpn в дальнейшем будет раздавать ип адреса клиентам в зависимостиот CommonName сертификата на Etoken практически - это аутентификация через ип - это аутентификация через Etoken) и логин/пароль, шифрование этих данных средствами realcrypt (unix-название truecrypt) (отмечу, что папки в данном контексте - те же файлы, и далее применяя разрешения на них нужно это понимать). Что отличает эту статью от того что в избытке можно встретить в интернете?
Здесь я рассмотрю применение наизамечательнейшей технологии
ACL в совокупности с собственно Samb'ой. В интернете масса статей по этому, но все их отличает крайняя степень простоты (многие рассматривают Samba как домашний файловый сервер) и никто из авторов не углубляется в данную тему. Собственно я не нашел ни одного решения позволяющего обеспечить разный доступ к одной папке нескольких пользователей. Возможно я ошибаюсь и этот HOWTO в таком случае будет полезен только для меня
2. Realcrypt
Итак, создадим шифрованный виртуальный логический диск data на котором в дальнейшем будет находиться файловое хранилище Samba.
Ставим realcrypt:
[root@localhost user1]# urpmi realcrypt
Создаем новый раздел realcrypt под названием realvolume в текущей директории. Размером 2 гигабайта. Обратите внимание - дисковую систему выбираем none (впрочем, это не критично). В будущем нам придется переразметить виртуальный логический диск в систему ext2 или ext3 потому что на fat32 невозможно реализовать ACL за счет ее особенностей.
[root@localhost folder]# realcrypt -t -c realvolume
Volume type:
1) Normal
2) Hidden
Select [1]: 1
Enter volume size (sizeK/size[M]/sizeG): 2G
Encryption algorithm:
1) AES
2) Serpent
3) Twofish
4) AES-Twofish
5) AES-Twofish-Serpent
6) Serpent-AES
7) Serpent-Twofish-AES
8) Twofish-Serpent
Select [1]: 1
Hash algorithm:
1) RIPEMD-160
2) SHA-512
3) Whirlpool
Select [1]: 1
Filesystem:
1) FAT
2) None
Select [1]: 2
Enter password:
WARNING: Short passwords are easy to crack using brute force techniques!
We recommend choosing a password consisting of more than 20 characters. Are you sure you want to use a short password? (y=Yes/n=No) [No]: y
Re-enter password:
Enter keyfile path [none]:
Please type at least 320 randomly chosen characters and then press Enter:
dsjklsdfailjsdfjilsdjiosdgjkl;djkowefopsdafopasdfjkosdgklsdgkjlsdgjklsdgakl.....
Done: 34,028% Speed: 36,7 MB/s Left: 92 s
Ждем пока создается наш образ диска. После чего монтируем его без монтирования файловой системы:
[root@localhost folder]# realcrypt -t --filesystem=none realvolume
Enter password for /media/true/folder/realvolume:
Enter keyfile [none]:
Protect hidden volume? (y=Yes/n=No) [No]:
Размечаем в ext2 (соответственно устройство находится в /dev/mapper/realcrypt1 если путь другой - поправить соответственно в команде)
[root@localhost mapper]# mkfs.ext2 /dev/mapper/realcrypt1
mke2fs 1.41.2 (02-Oct-2008)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
131072 inodes, 524224 blocks
26211 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=536870912
16 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 32 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
Правим fstab:
[root@localhost data]# vi /etc/fstab
Нужно дописать строчку -
/dev/mapper/realcrypt1 /media/data ext2 acl 1 1
В принципе, можно сразу указать при монтировании раздела поддержку acl. Подобное включение ACL для других дисков (не только для realcrypt'овских volume) делается точно так же.
Т.е. к примеру для каталога /var добавляем acl:
<путь_до_устройства> /var ext3 acl,relatime 1 2
и перемонтируем:
[root@localhost ~]# mount /var -o remount
Смотрим, есть ли acl на наших примонтированных дисках:
[root@localhost media]# mount
....
....
....
/dev/mapper/realcrypt2 on /media/data type ext2 (rw,acl)
Есть. можно продолжать
3. Введение в ACL.
Почему же была выбрана технология ACL?
Дело в том что в Samb'е (к примеру) очень (на мой взгляд) странно реализована система раздачи доступов на расшаренные ей папки. Ее странность заключается в том, что чтобы дать доступ определенному пользователю на папку нужно создать этого пользователя (и дать соответственно доступ) не только в самой Самбе но и в самой операционной системе.
А инструментарий управления доступом в Unix чрезвычайно беден (chown, chmod, членство в группах) и не позволяет, к примеру, дать двум-трем-четырем пользователям различающееся права на одну и ту же папку/файл. Здесь на помощь приходит ACL.
3.1 Настройка ACL.
Итак изначально нам нужно установить собственно ACL.
[root@localhost user1]# urpmi acl
После его установки, и перемонтировании разделов с его поддержкой (как - написано выше) можно начинать с ним работать следующими командами:
Пример:
setfacl -R -m u:user1:rwx /media/data/user1
setfacl -R -m u:user2:rwx /media/data/user1
При успешном выполнении команды рядом со стандартным "drwxrwxr-x" появится плюс. Обратите внимание на то что владельцем директории является root - собственно это не важно кто User1 все равно будет иметь туда доступ.
[root@localhost data]# ll
итого 24
drwx------ 2 root root 16384 2008-11-27 17:03 lost+found/
drwxrwxr-x+ 2 root root 4096 2008-11-27 17:37 user1/
Что здесь что - мы задаем доступ на папку user1 таким образом что кроме user1 на нее получает так же полный доступ и user2.
Параметры обозначают следующее:
-R - рекурсивно (на все папки, подпапки и файлы в директории)
-m - от слова modify, т.е. этот параметр говорит что мы будем модифицировать ACL папки
u:user1:rwx - собственно дать пользователю user1 доступ на папку - читать, писать, и исполнять ее содержимое (в частности для того чтобы пользователь мог открыть файлы в папке (и саму папку) запись должна быть такой - u:user1:rx).
/media/data/user1 - собственно путь к папке(файлу) на который задается доступ.
getfacl /media/data/user1 - разрешения на папку /media/data/user1
Выведет примерно следующее:
[root@localhost /]# getfacl media/data/user1/
# file: media/data/user1/
# owner: root
# group: root
user::rwx
user:user1:rwx
group::r-x
mask::rwx
other::r-x
А теперь подумаем, что будет если user1 создаст новый файл в своей папке? Какие по умолчанию разрешения будут ему назначаться?
Разрешения в данном случае будут назначаться системные - по умолчанию без того ACL что мы ставили на директорию верхнего уровня. То есть "drwxrwxr-x 2 root root " в данном случае.
Чтобы этого избежать используется конструкция следующего вида:
setfacl -R -m default:u:user1:rwx /media/data/user1
default:u:user1:rwx - говорит о том что на все все файлы создаваемые в директории user1 по умолчанию будет назначаться права на запись, чтение, и исполнение для user1. И, разумеется, сам default. Т.о. вывод команды getfacl на некую директорию и некий файл созданные кему угодно в директории user1 будут такими:
[root@localhost /]# setfacl -R -m default:u:user1:rwx /media/data/user1
[root@localhost /]# getfacl media/data/user1/
# file: media/data/user1/
# owner: root
# group: root
user::rwx
user:user1:rwx
group::r-x
mask::rwx
other::r-x
default:user::rwx
default:user:user1:rwx
default:group::r-x
default:mask::rwx
default:other::r-x
[root@localhost /]# cd /media/data/user1
[root@localhost user1]# echo chtougodno > file
[root@localhost user1]# ll
итого 4
-rw-rw-r--+ 1 root root 11 2008-11-27 14:51 file
[root@localhost user1]# getfacl file
# file: file
# owner: root
# group: root
user::rw-
user:user1:rwx #effective:rw-
group::r-x #effective:r--
mask::rw-
other::r--
[root@localhost user1]# mkdir newdir
[root@localhost user1]# getfacl newdir
# file: newdir
# owner: root
# group: root
user::rwx
user:user1:rwx
group::r-x
mask::rwx
other::r-x
default:user::rwx
default:user:user1:rwx
default:group::r-x
default:mask::rwx
default:other::r-x
ВНИМАНИЕ! User2 в данном случае сможет зайти в папку media/data/user1 но не сможет читать в ней никакие файлы и заходить в директорию newdir. Так как на него default мы не прописывали
Таким образом, мы можем создавать достаточно гибкие разрешения на любые папки и файлы на нашем будущем файловом сервере. Что и требуется в случае Самбы.
4. Samba введение.
Самба
это Протокол SMB.
(Материал из Википедии - свободной энциклопедии)
SMB (сокр. от англ. server message block) - формат сообщений на основе протокола совместного использования файлов Microsoft/3Com, используемый для передачи файловых запросов (open - открыть, close - закрыть, read - прочитать, write - записать и т. п.) между клиентами и серверами.
SMB обеспечивает сервис прикладного уровня (уровень 7 «Application layer» в модели OSI) и используется в таких сетевых платформах, как LAN Manager, LAN Server, Windows NT. По умолчанию имеет номер порта 139. Данный порт будет использоваться при установке соединения клиента с сервером.
Установим Samb'у:
[root@localhost user1]# urpmi samba
Настройка Samba. В конфиге к ней есть масса комментариев и прочего, здесь я все это вырезал дабы не занимать места. Разумеется с рабочим файлом самбы таким варваровским способом поступать не стоит. А комментировать буду наиболее важные вещи.
[root@localhost samba]# vi /etc/samba/smb.conf
[global]
workgroup = WORKGROUP
netbios name = FileServer
server string = Main Server
# Отрубаем шару принтер
# То есть вообще отрубаем - дабы даже видно не было :)
# Возможно потом мы ее настроим но сейчас она не нужна
disable spoolss = Yes
show add printer wizard = No
log file = /var/log/samba/%m.log
max log size = 50
# Диапазоны IP адресов с которых разрешен доступ, можно по маске.
# В данном случае доступ разрешен только с сетки 10.8.0.0 (это будущая сетка openvpn, о настройке которого мы поговорим потом)
# и запрещен со всего остального.
hosts allow = 10.8.0.0/24 127.0.0.1
hosts deny = 0.0.0.0/0
security = user
encrypt passwords = yes
encrypt passwords = yes
smb passwd file = /etc/samba/smbpasswd
# Звездочка значит слушать все интерфейсы. К сожалению почему-то не получилось заставить самбу слушать только
# виртуальный интерфейс который создается при включении openvpn сервиса. Поэтому звездочка :)
interfaces = *
dns proxy = no
preserve case = yes
case sensitive = no
# Очень важный блок который говорит самбе что на иксах использовать кодировку utf8
# А для Windows - cp1251. В том числе (по идее) отвечает и за перекодировку имен файлов скопированных
# из Windows в utf8 и обратно (потому как хранится все в нем)
dos charset = 932
windows charset = cp1251
unix charset = utf8
#============================ Share Definitions ==============================
# Определение шары. Строка user = user1 необязательна.
[user1]
comment = user1
path = /media/data/user1
public = yes
guest ok = no
writable = yes
printable = no
#user = user1
Да! не забудем дать чмод на директорию пользователя.
[root@localhost media]# chmod -R 771 /media/data/
Добавляем user1 в самбу
[root@localhost user1]# smbpasswd -a user1
New SMB password:
Retype new SMB password:
Added user user1.
Внеся изменения перезапускаем samba:
[root@localhost user1]# service smb restart
Останавливаются службы SMB: [ OK ]
Останавливаются службы NMB: [ OK ]
Запускаются службы SMB: [ OK ]
Запускаются службы NMB: [ OK ]
Права на папку user1 мы уже задали раньше - в настройке ACL.
ВНИМАНИЕ! Пользователь user1 должен быть заведен как в OC (useradd user1) так и в самбе способом описанным выше.
Теперь (разумеется после того как мы поправим список интерфейсов в самбе, которые сейчас разрешают доступ исключительно сетке 10.8.0.0, и перезапустим самбу) постучавшись на сервер с установленной самбой и введя самбовский пароль на user1 мы сможем зайти в его папку.
Все остальные разрешения задаются аналогично в системе через setfacl.
ВНИМАНИЕ!!! Не стоит забывать про фаервалл запущенный на сервере (если вы собираетесь тестить самбу из внешней сети то стоит подумать над тем что нужно открыть порты). А так же не стоит забывать про ip адрес вашего хоста - его нужно внести в Allowed hosts иначе естественно ничего работать не будет. Впрочем, логи Самбы хранятся в var/log/samba и посмотреть в чем заключается проблема не составит труда (по ип адресам или хостнейм компьютера с которого производите подключение)
Теперь мы можем проверить как работает наша самба делается это простой утилиткой smbclient:
[root@localhost]# smbclient \\\\localhost\\user1 -U user1
здесь localhost - хост на который мы будем подключаться, user1 - папка в которую мы будем подключаться, -U user1 - юзер под кем мы будем это делать. (разумеется localhost (127.0.0.1) должен быть в Allow Host в конфиге самбы)
Теперь самое интересное. А если самба находится не в домашней локальной сети а на сервере в интернете? и открывать порты наружу не хочется ну вовсе?
Здесь нам на помощь придет проброс портов по ssh. Пробрасывать будем три порта.
"Приложения могут через netbios найти нужные им ресурсы, установить связь и послать или получить информацию. NETBIOS использует для службы имен порт - 137, для службы дейтограмм - порт 138, а для сессий - порт 139.
(c)" (netbios в данном случае - тот же smb протокол)
ssh -L 5555:localhost:139 user@удаленный ip-адрес
это строка значит - прокинуть порт с удаленного компьютера (L) на локальный (двоеточие означает localhost или 127.0.0.1) таким образом чтобы при обращении на локальный порт 5555 перекидывало на порт 139 удаленного ип-адреса. User собственно юзер под кем логинитсья на удаленном сервере.
после проброса (вроде для smbclient вообще достаточно одного порта - 139 )
команда smbclient примет следующий вид:
[root@localhost ~]# smbclient \\\\localhost\\user1 -U user1 -p 5555
После чего можно проверить
Проброс портов.
В главе про самбу мы впервые столкнулись с возможностью проброса портов на сервера. Это также может быть использовано для любых целей (например для коннекта Apache Directory Studio к Ldap базе данных).
Синтаксис этой команды понятен:
ssh -L 5555:localhost:139 user@удаленный ip-адрес
Под виндой для этих же целей можно использовать putty:
C:\Documents and Settings\Oleg>putty -L 5555::139 user@192.168.10.229
"это строка значит - прокинуть порт с удаленного компьютера (L) на локальный (двоеточие означает localhost или 127.0.0.1) таким образом чтобы при обращении на локальный порт 5555 перекидывало на порт 139 удаленного ип-адреса. User1 собственно юзер под кем логинитсья на удаленном сервере. " (с)
Настройка доступа по ip к шарам.
Итак, пусть OpenVpn сервер (о настройке которого мы поговорим позже). Настроен таким образом что каждому клиенту (согласно имени Common Name сертификата клиента) назначается отдельная подсеть с ип адресом. (Например 10.8.0.0 255.255.255.252)
Мы хотим чтобы клиент только под определенным ипишником мог применять пароль к определенной папке. Иначе получится ситуация что клиент может подконнетиться с любым сертификатом, и, если он узнает пароль другого пользователя - зайти в его папку.
Конструкция на самом деле проста:
Заккоментируем в самбе строчки вида:
hosts allow = 10.8.0.0/24 127.0.0.1
hosts deny = 0.0.0.0/0
И дальше в описании шары добавим еще две строчки:
allow hosts = 10.8.0.21
deny hosts = 0.0.0.0/0
Т.е. описание шары user1 примет вид:
[user1]
comment = user1
path = /media/true/folder/user1
public = yes
guest ok = no
writable = yes
printable = no
#user = user1
allow hosts = 10.8.0.21
deny hosts = 0.0.0.0/0
Не забудем прописать в /etc/passwd /sbin/nologin как командный интерпретатор на всех вновь создаваемых юзеров.
Т.е.
user1:x:501:501::/home/user1:/sbin/nologin
Пожалуй все