- PVSM.RU - https://www.pvsm.ru -

Принт-сервер на linux с интеграцией в AD

В данной статье я хотел поселиться опытом по созданию принт-сервера на базе linux с интеграцией в AD. Под интеграцией понимается ввод linux сервера в домен Windows и расшаривание Cups принтеров через Samba, включая драйвера принтеров. Возможно коряво выразился, но если проще, то это выглядит так — для того, чтобы установить принтер пользователю Windows, достаточно нажать«установить новый принтер», вывести список принтеров в AD и клацнуть на нужный принтер — принтер установится автоматически с установкой всех необходимых драйверов. При этом, все права на управление, доступ, печать подтянутся из AD.

Часть 1. Тонкости настроек

Исходные данные

  • Домен контроллер — Windows Server 2008 R2 (AD, DNS, DHCP) IP — 10.10.15.31
  • Имя домена — INITIAL
  • Принт сервер — ОС linux (я использую OpenSUSE 13.2 x64, kernel 3.16.7-42-default) IP — 10.10.15.11
  • kerberos 1.12.2-24.1
  • winbind 4.2.4-40.1
  • LDAP 2.4.39-8.9.1
  • Samba 4.2.4-40.1
  • CUPS 1.5.4-21.9.1


Предположим, что ОС linux уже установлена и установлены все необходимые пакеты.
На вводе linux в домен Winodws не буду заострять много внимания, тем более, что статей на эту тему предостаточно. Приведу ссылку на довольно неплохую статью — https://habrahabr.ru/post/143190/ [1]
Остановлюсь лишь на важных моментах. Так же, ниже выложу все свои рабочие конфиги вышеуказанных сервисов. Настраивал по разным статьям и мануалам.

Синхронизация времени

Время на linux сервере должно быть идентичным с домен контроллером, иначе в домен не вогнать.
Для этого есть несколько вариантов: на домен контроллере и нашем принт сервере указать одни и те же ntp сервера синхронизации времени или на принт сервере указать IP домен контроллера в качестве ntp сервера. Я настроил по второму варианту.

/etc/ntp.conf
server 10.10.15.31 iburst

Проверить синхронизацию можно так:

print-01:~ # ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
*10.10.15.31     85.236.191.80    3 u  888 1024  377    0.698    6.690   7.232

Winbind

/etc/nsswitch.conf
passwd: files winbind
group: files winbind
shadow: files winbind
hosts:	files mdns4_minimal [NOTFOUND=return] dns wins

Многие утверждают, что данные настройки вообще не нужны для samba, как и kerberos и LDAP, но я люблю все по феншую ))). Ранее я настраивал samba в качестве PDC (Primary Domain Controller) без kerberos и LDAP и все это работало с WinXP клиентами, подтверждаю.

/etc/samba/smb.conf
winbind separator = /
winbind enum users = Yes
winbind enum groups = Yes
winbind use default domain = Yes
winbind nss info = rfc2307
winbind refresh tickets = Yes

Samba

/etc/samba/smb.conf
idmap uid = 500-10000000
idmap gid = 500-10000000
idmap backend = ldap:ldap://10.10.15.31

Данные настройки не рекомендуются самой samba, начиная с каких то версий 3.Х, но во многих статьях они указываются. Если указать данные параметры в новых версиях самбы, то testparm выдаст:

print-01:/etc/samba # testparm -v
Load smb config files from /etc/samba/smb.conf
WARNING: The "idmap backend" option is deprecated
WARNING: The "idmap gid" option is deprecated
WARNING: The "idmap uid" option is deprecated

параметр realm — имя домена должно быть указано заглавными буквами!

realm = DOMAIN.COM

Kerberos

Секция realms — имя домена должно быть указано заглавными буквами!

/etc/krb5.conf
[realms]
DOMAIN.COM = {...

Иначе, можно получить такую ошибку при проверке kerberos

kinit username@DOMAIN.COM
kinit(v5): KDC reply did not match expectations while getting initial credentials

Предположим, что вы настроили необходимые сервисы и успешно ввели linux машину в домен Windows. Перейдем к настройкам CUPS.

CUPS

/etc/cups/cupsd.conf
# Изменим уровень логирования на период отладки
LogLevel debug 

# Системная группа (добавлять, удалять принтеры, менять их конфигурацию может только root)
SystemGroup root

# Слушаем соединения на порту 631 / Listen for connections on Port 631.
Port 631
Listen /run/cups/cups.sock
BrowseLocalProtocols CUPS
BrowseRemoteProtocols CUPS

# Расшариваем принтеры в локальной сети / Show shared printers on the local network.
Browsing On
BrowseOrder allow,deny
BrowseAllow all
BrowseAddress 10.10.15.0/24
BrowseAddress 172.19.2.0/24
BrowseAddress 172.19.3.0/24
BrowseAddress 172.19.4.0/24
# Default authentication type, when authentication is required...
DefaultAuthType Basic
WebInterface Yes

Здесь поясню.

BrowseOrder allow,deny — порядок рассмотрения системой разрешающих и запрещающих директив: все что не разрешено — запрещено.
BrowseAllow all — отображения всех доступных принтеров локальной сети
BrowseAddress — указываем все подсети, из которых нужен доступ к принтерам
DefaultAuthType — тип аутентификации. По умолчанию — Basic.

На счет последнего. Заметил в логох следующее:

/var/log/cups/error_log
cupsdAuthorize: No authentication data provided.

Рекомендации на эту тему нашел две:

— отключить шаринг принтеров в самбе полностью (очень полезно, особенно для сервера печати)
— заменить Basic на None везде, где есть данная опция в cupsd.conf (не почувствовал разницы)

На cups.org вычитал, что значений данной опции может быть 2 — Basic и Negotiate, последняя для аутентификации с использованием kerberos.

В любом случае, данная ошибка никак не влияет на работу cups'a.

# Разрешаем доступ к серверу печати со всех машин локальной сети.
<Location />
  # Allow remote access...
  Order allow,deny
  Allow all
</Location>

Я указал доступ для всех локальных подсетей. В принципе в директиве Allow можно указать разные подсети, так же, как я делал это в BrowseAddress.

Далее настраиваем доступ к административной панели и конфигурационным файлам. Здесь можно так же прописать директиву Allow (в каждую секцию) с указанием подсетей или отдельного IP адреса, с которого/которых можно будет администрировать принтеры. Если не добавлять эту директиву — админить можно будет с любой подсети локалки — равнозначно Allow all.

<Location /admin>
 Order allow,deny
</Location>
<Location /admin/conf>
  AuthType Default
  Require user @SYSTEM
</Location>

На этом настройка cups закончена. Рестартим его. В OpenSUSE это делается через systemctl

systemctl restart cups.service

Теперь можно приступить к настройке принтеров через web интерфейс cups'a. Есть небольшая тонкость — для изменения, добавления, удаления принтеров необходимо заходить в web интерфейс cups по ssl (https), т.е. в веб браузере открываем

https://10.10.15.11:631/ 

Иначе получим такую ошибку:

Принт-сервер на linux с интеграцией в AD - 1 [2]

Добавлять принтеры в cups через web интерфейс задача — довольно тривиальная, поэтому описывать не буду. Единственное, рекомендую на вкладе «Администрирование» проверить включены ли опции:

— Разрешить совместный доступ к принтерам, подключенным к этой системе
— Разрешить печать из Интернета

И при установке принтера, не забывать включать опцию «Разрешить совместный доступ к этому принтеру».

Принт-сервер на linux с интеграцией в AD - 2 [3]

Кто не хочет заморачиваться с samba, в cups есть возможность печати посредством протокола ipp (Internet Printing Protocol). В Windows принтер устанавливается так: панель управления → принтеры → установка принтера → сетевой принтер → подключиться к принтеру в интернете («выбрать общий принтер по имени» для Win7/8/10) в качестве url указываем полный путь:

Например http://10.10.15.11:631/printers/Kyocera_6525_PTO 
Или http://Print-01:631/printers/Kyocera_6525_PTO

Принт-сервер на linux с интеграцией в AD - 3 [4]

Принт-сервер на linux с интеграцией в AD - 4

Полный путь до принтера можно скопировать из адресной строки браузера в web интерфейсе cups.

Принт-сервер на linux с интеграцией в AD - 5 [5]

Единственное, при данном способе система запросит драйвер принтера. Его нужно будет предварительно скачать и скормить ей при установке.

ГРАБЛЯ_№1: в WinXP протокол ipp включен по дефолту в сервис пак начиная с SP2, в Windows7/8/10 компонент «Интернет печать» может быть не включен.

Устанавливается через панель управления → программы и компоненты — включение и отключение компонентов Windows. В серверных Windows, данный протокол точно отключен по дефолту. Включаем через диспетчер сервера → компоненты → добавить компоненты → клиент печати через Интернет.

Я промучался с этой проблемой 2 дня. При попытке установки принтера данным способом вылезала ошибка — «Windows не удается подключиться к принтеру». При этом в логах cups и samba — ничего криминального нет. Это был мегатреш. Я дошел до разбора всего потока сетевого интерфейса с помощью tcpdump и wireshark, но ларчик то просто открывался. Проблема была на стороне винды.

Принт-сервер на linux с интеграцией в AD - 6

Часть 2. Установка драйверов

Предположим, что принтеры в cups установлены, теперь приступим к копированию и регистрированию драйверов принтеров для Windows.

Можно вручную скопировать установленные драйверы в Windows — %WINDIR%system32spooldriversW32X86 и x64 в папку с шарой для драйверов samba — /var/lib/samba/drivers/W32X86 и ./x64 и потом регистрировать их с помощью консольной утилиты rpcclient, но это нереальный квест и занятие не для слабонервных.

Мы пойдем более простым путем. Логинимся на виндовой машине с учеткой Domain Admin в наш домен. Буду показывать на примере WinXP (далее расскажу как действовать с Win7). Открываем проводник, в адресной строке вбиваем адрес принт сервера по IP или имени: \Print-01 или \10.10.15.11, переходим в папку Принтеры и факсы.

Принт-сервер на linux с интеграцией в AD - 7 [6]

Клацаем правой кнопкой мыши на принтере → свойства.

Принт-сервер на linux с интеграцией в AD - 8 [7]

На предложение установить драйвер, говорим Нет.

Принт-сервер на linux с интеграцией в AD - 9 [8]

Идем во вкладку «дополнительно» → сменить.

Принт-сервер на linux с интеграцией в AD - 10


Установить с диска и указываем папку с драйвером. Выбираем принтер в списке и нажимаем ОК.

ВАЖНО — в начале необходимо указать папу с 32-битными драйверами, даже, если система у вас 64-битная! 64-битные дрова установить можно будет после.

Принт-сервер на linux с интеграцией в AD - 11


Идет копирование драйверов в расшаренную папку samba.

Принт-сервер на linux с интеграцией в AD - 12


Переходим во вкладку «доступ» → отмечаем галочку «Внести в Active Diectory» → применить. Если нужны 64-битные драйвера, нажимаем Дополнительные драйвера"

Принт-сервер на linux с интеграцией в AD - 13


И отмечаем галочку х64 → ОК. Система запросит папку с драйверами — аналогично скармливаем ей ее.

Принт-сервер на linux с интеграцией в AD - 14


При желании, на вкладке «Общие», можно переименовать сетевой принтер. Эти названия будут отображаться при переходе в проводнике на принтсервер \Print-01 или \10.10.15.11.

Принт-сервер на linux с интеграцией в AD - 15


В AD имена принтеров будут теми же, как вы называли их в cups.

Принт-сервер на linux с интеграцией в AD - 16

Удаление принтеров из AD.

Диспетчер сервера → Доменные службы Active Directory → Active Directory пользователи и компьютеры → выбираем домен правой кнопкой мыши → найти → выбираем группу из ниспадающего списка «принтеры» → найти.

Принт-сервер на linux с интеграцией в AD - 17 [9]

Находим в списке принтер, который хотим удалить → правой кнопкой мыши «удалить»

Принт-сервер на linux с интеграцией в AD - 18 [10]

Установка драйверов в Windows 7/8/10.

В Windows 7/8/10 установить драйвера на принт-сервер можно из оснастки printmanagement.msc. Пуск → выполнить → printmanagement.msc

ПРИМЕЧАНИЕ В Home и Home Premium этой тулзы нет. Запускать эту оснастку нужно из под учетки Domain Admin. Сначала нужно добавить наш сервер печати по IP или имени.

Принт-сервер на linux с интеграцией в AD - 19 [11]

Далее, здесь можно управлять принтерами сервера печати по аналогии c вышеуказанной инструкцией.

Принт-сервер на linux с интеграцией в AD - 20 [12]

Так же здесь удобно управлять драйверами сервера печати — удалять/добавлять.

Принт-сервер на linux с интеграцией в AD - 21 [13]

Что не удалось пока решить

В Windows Server 2012 R2 ну никак не хотят устанавливаться расшаренные принтеры. Ошибок в логах cups и samba нет. Принер начинает устанавливаться, драйвера копируются, но на этапе «завершение установки» выскакивает вышеуказанная ошибка «Windows не удается подключиться к принтеру». Думаю это какой-то косяк винды и скорее всего протокола ipp, хотя компонент «Клиент интернет печати» установлен.

В заключении, поделюсь секретом установки принтера Panasonic KX-FLB883RU в CUPS. Для данного принтера нет драйверов для linux, но чудесным образом подошел ljet2p.ppd (Panasonic KX-P4410 Foomatic/ljet2p), входящий в стандартный пакет OpenPrintingPPDs. Настройка принтера в CUPS через socket://IP_address/. Все работает без глюков. Надеюсь, кому-то пригодится.

Следующая моя статья будет посвящена удаленной автоматизированной системе установки принтеров пользователям домена. Или как то так)

Мои рабочие конфиги см. ниже.

/etc/krb5.conf

[libdefaults]
	ticket_lifetime = 24000
	default_realm = INITIAL.LOCAL
	dns_lookup_realm = false
	dns_lookup_kds = false
	clockskew = 300
# -------------------------------------
	kdc_timesync = 1
	ccache_type = 4
	forwardable = true
	proxiable = true

[realms]
INITIAL.LOCAL = {
	kdc = dc-01.initial.local
	default_domain = initial.local
#	admin_server = kerberos.initial.local:749
	admin_server = dc-01.initial.local
}

# EXAMPLE.COM = {
# 	kdc = kerberos.example.com
# 	admin_server = kerberos.example.com
# }

[logging]
	kdc = FILE:/var/log/krb5/krb5kdc.log
	admin_server = FILE:/var/log/krb5/kadmind.log
	default = SYSLOG:NOTICE:DAEMON
[domain_realm]
	.initial.local = INITIAL.LOCAL
	.INITIAL.local = INITIAL.LOCAL
	.INITIAL = INITIAL.LOCAL
	initial.local = INITIAL.LOCAL
[appdefaults]
pam = {
	debug = false
	ticket_lifetime = 1d
	renew_lifetime = 1d
	forwardable = true
	proxiable = false
	retain_after_close = false
	minimum_uid = 1
	use_shmem = sshd
	clockskew = 300
}

/etc/nsswitch.conf

# /etc/nsswitch.conf
#
# An example Name Service Switch config file. This file should be
# sorted with the most-used services at the beginning.
#
# The entry '[NOTFOUND=return]' means that the search for an
# entry should stop if the search in the previous entry turned
# up nothing. Note that if the search failed due to some other reason
# (like no NIS server responding) then the search continues with the
# next entry.
#
# Legal entries are:
#
#       compat                  Use compatibility setup
#       nisplus                 Use NIS+ (NIS version 3)
#       nis                     Use NIS (NIS version 2), also called YP
#       dns                     Use DNS (Domain Name Service)
#       files                   Use the local files
#       [NOTFOUND=return]       Stop searching if not found so far
#
# For more information, please read the nsswitch.conf.5 manual page.
#

# passwd: files nis
# shadow: files nis
# group:  files nis

# passwd:	compat winbind
# group:	compat winbind
# shadow:	compat winbind

passwd:	files winbind
group:	files winbind
shadow:	files winbind

# hosts:	files mdns4_minimal [NOTFOUND=return] dns wins
# hosts:	files [dns] wins
hosts:	files mdns4_minimal [NOTFOUND=return] dns wins

networks:	files dns
services:	files
protocols:	files
rpc:	files
ethers:	files
netmasks:	files
netgroup:	files nis
publickey:	files

bootparams:	files
automount:	files nis
aliases:	files

/etc/openldap/ldap.conf

#
# LDAP Defaults
#

# See ldap.conf(5) for details
# This file should be world readable but not world writable.

#BASE	dc=example,dc=com
#URI	ldap://ldap.example.com ldap://ldap-master.example.com:666

#SIZELIMIT	12
#TIMELIMIT	15
#DEREF		never
URI	ldap://10.10.15.31
BASE	DC=initial,DC=local

/etc/samba/smb.conf

# smb.conf is the main Samba configuration file. You find a full commented
# version at /usr/share/doc/packages/samba/examples/smb.conf.SUSE if the
# samba-doc package is installed.
[global]
	workgroup = INITIAL
#	passdb backend = smbpasswd
	printing = cups
	printcap name = cups
	printcap cache time = 750
	cups options = raw
	map to guest = Bad User
	logon path = \%Lprofiles.msprofile
	logon home = \%L%U.9xprofile
	logon drive = P:
	usershare allow guests = Yes
	add machine script = /usr/sbin/useradd  -c Machine -d /var/lib/nobody -s /bin/false %m$
	domain logons = No
	domain master = No
	security = ADS
	encrypt passwords = yes
#	idmap backend = ldap:ldap://10.10.15.31
	ldap admin dn = admin@initial.local
	ldap group suffix = ou=Groups
	ldap idmap suffix = ou=Idmap
	ldap machine suffix = ou=Computers
	ldap passwd sync = Yes
	ldap suffix = DC=initial,DC=local
	ldap user suffix = ou=Users
	ldap ssl = Off
	ldapsam:trusted = yes
	ldapsam:editposix = yes
#	idmap gid = 500-10000000
#	idmap uid = 500-10000000
	netbios name = print-01
	name resolve order = lmhost wins host bcast
	wins server = 10.10.15.31
	wins support = No
	usershare max shares = 100
	kerberos method = system keytab
## --------------------------------------
	winbind separator = /
	winbind enum users = yes
	winbind enum groups = yes
	winbind nested groups = yes
	winbind use default domain = yes
	winbind nss info = rfc2307
	winbind uid = 10000-20000
	winbind gid = 10000-20000
	realm = INITIAL.LOCAL
	template homedir = /home/%D/%U
	winbind refresh tickets = yes
	template shell = /bin/bash

# [homes]
#	comment = Home Directories
#	valid users = %S, %D%w%S
#	browseable = No
#	read only = No
#	inherit acls = Yes

# [profiles]
#	comment = Network Profiles Service
#	path = %H
#	read only = No
#	store dos attributes = Yes
#	create mask = 0600
#	directory mask = 0700

# [users]
#	comment = All users
#	path = /home
#	read only = No
#	inherit acls = Yes
#	veto files = /aquota.user/groups/shares/
#	guest ok = No

# [groups]
#	comment = All groups
#	path = /home/groups
#	read only = No
#	inherit acls = Yes

[printers]
	comment = All Printers
	path = /var/spool/samba
	printable = Yes
	create mask = 0664
	browseable = Yes
	read only = No
	guest ok = Yes

[print$]
	comment = Printer Drivers
	path = /var/lib/samba/drivers
	write list = @ntadmin root
	force group = ntadmin
	create mask = 0664
	directory mask = 0700
	read only = No
	guest ok = Yes
	writable = yes
#	inherit permissions = yes
# --------------------------------
	use client driver = yes

# [netlogon]

/etc/cups/cupsd.conf

LogLevel debug
SystemGroup root
# Allow remote access
Port 631
Listen /run/cups/cups.sock
Browsing On
BrowseLocalProtocols CUPS
BrowseRemoteProtocols CUPS
BrowseOrder allow,deny
BrowseAllow all
BrowseAddress 10.10.15.0/24
BrowseAddress 172.19.2.0/24
BrowseAddress 172.19.3.0/24
BrowseAddress 172.19.4.0/24
DefaultAuthType Basic
WebInterface Yes
<Location />
  # Allow remote access...
  Order allow,deny
  Allow all
</Location>
<Location /admin>
  Order deny,allow
</Location>
<Location /admin/conf>
  AuthType Default
  Require user @SYSTEM
</Location>
<Policy default>
  JobPrivateAccess default
  JobPrivateValues default
  SubscriptionPrivateAccess default
  SubscriptionPrivateValues default
  <Limit Create-Job Print-Job Print-URI Validate-Job>
    Order deny,allow
  </Limit>
  <Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job Cancel-My-Jobs Close-Job CUPS-Move-Job CUPS-Get-Document>
    Require user @OWNER @SYSTEM
    Order deny,allow
  </Limit>
  <Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class CUPS-Delete-Class CUPS-Set-Default CUPS-Get-Devices>
    AuthType Default
    Require user @SYSTEM
    Order deny,allow
  </Limit>
  <Limit Pause-Printer Resume-Printer Enable-Printer Disable-Printer Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer Startup-Printer Promote-Job Schedule-Job-After Cancel-Jobs CUPS-Accept-Jobs CUPS-Reject-Jobs>
    AuthType Default
    Require user @SYSTEM
    Order deny,allow
  </Limit>
  <Limit Cancel-Job CUPS-Authenticate-Job>
    Require user @OWNER @SYSTEM
    Order deny,allow
  </Limit>
  <Limit All>
    Order deny,allow
  </Limit>
</Policy>
<Policy authenticated>
  JobPrivateAccess default
  JobPrivateValues default
  SubscriptionPrivateAccess default
  SubscriptionPrivateValues default
  <Limit Create-Job Print-Job Print-URI Validate-Job>
    AuthType Default
    Order deny,allow
  </Limit>
  <Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job Cancel-My-Jobs Close-Job CUPS-Move-Job CUPS-Get-Document>
    AuthType Default
    Require user @OWNER @SYSTEM
    Order deny,allow
  </Limit>
  <Limit CUPS-Add-Modify-Printer CUPS-Delete-Printer CUPS-Add-Modify-Class CUPS-Delete-Class CUPS-Set-Default>
    AuthType Default
    Require user @SYSTEM
    Order deny,allow
  </Limit>
  <Limit Pause-Printer Resume-Printer Enable-Printer Disable-Printer Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer Startup-Printer Promote-Job Schedule-Job-After Cancel-Jobs CUPS-Accept-Jobs CUPS-Reject-Jobs>
    AuthType Default
    Require user @SYSTEM
    Order deny,allow
  </Limit>
  <Limit Cancel-Job CUPS-Authenticate-Job>
    AuthType Default
    Require user @OWNER @SYSTEM
    Order deny,allow
  </Limit>
  <Limit All>
    Order deny,allow
  </Limit>
</Policy>
<Policy allowallforanybody>
  JobPrivateAccess all
  JobPrivateValues none
  SubscriptionPrivateAccess all
  SubscriptionPrivateValues none
  <Limit All Validate-Job Cancel-Jobs Cancel-My-Jobs Close-Job CUPS-Get-Document>
    Order deny,allow
    Allow from all
  </Limit>
</Policy>
DefaultPolicy default

Спасибо за внимание!

Автор: Bearpuh

Источник [14]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/it-infrastruktura/203111

Ссылки в тексте:

[1] https://habrahabr.ru/post/143190/: https://habrahabr.ru/post/143190/

[2] Image: http://hostingkartinok.com/show-image.php?id=9e9a0fe8c3142a0c40a76918426a0913

[3] Image: http://hostingkartinok.com/show-image.php?id=f3f371186f101af150a31f95109e868f

[4] Image: http://hostingkartinok.com/show-image.php?id=bd86db1e8978c8e6a4b24b8d161c469d

[5] Image: http://hostingkartinok.com/show-image.php?id=45009425fc291152bb3a48dada910cb8

[6] Image: http://hostingkartinok.com/show-image.php?id=88e6b2e2b2f9594d0d290d715e906a52

[7] Image: http://hostingkartinok.com/show-image.php?id=ca2e713d6691031dbbdbe596bab81230

[8] Image: http://hostingkartinok.com/show-image.php?id=a4f793e4920b4285a7ab5d86806ae833

[9] Image: http://hostingkartinok.com/show-image.php?id=9d18fccc4c31665bdc7bb32300460eab

[10] Image: http://hostingkartinok.com/show-image.php?id=b21230034cb92c108190b1c0699bf7f3

[11] Image: http://hostingkartinok.com/show-image.php?id=1e9cfe366129e0ca86ca753220e31322

[12] Image: http://hostingkartinok.com/show-image.php?id=2498ec01ec1e1b25dc56f8878e61150e

[13] Image: http://hostingkartinok.com/show-image.php?id=f6560021a31e997ca43aa747f7bd3416

[14] Источник: https://habrahabr.ru/post/313636/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best