воскресенье, 25 декабря 2016 г.

Ember автодополнение - выпадающий список - с использованием bootstrap


Использование html select это замечательно, но нет поля ввода, для того чтобы подгружать ограниченный список с бакэнда. В моем случае бакэнд выдает за раз 10 записей. Да и не разумно в select грузить 1000 записей. Поэтому, я сделал в Ember приложении для формы поля input автодополнение с выпадающим списком используя bootstrap button dropdown. Надо, конечно еще над дизайном выпадающего списка поработать, но данное решение рабочее и может использоваться в формах.


template.hbs

<form class="form-horizontal">
  <div class="form-group">
    <label class="col-sm-2 control-label">Customer:</label>
    <div class="top dropdown" id="search-bar">
      <span class="fa fa-search" id="btn-search" data-toggle="dropdown"></span>
      {{input type="text" value=personValue focus-in='focusedCustomer' key-up=(action 'handleFilterCustomer') autocomplete="off" class="form-control" placeholder="Enter customer name"}}
      <ul class="dropdown-menu">
        {{#each model.customers as |customer|}}
          <li class="list-group-item" onclick={{action "customerClick" customer.name customer.id}}>{{customer.name}}</li>
        {{/each}}
      </ul>
    </div>
  </div>
</form>


route.js

model() {
  return RSVP.hash({
    task: this.store.createRecord('task'),
    customers: this.store.peekAll('person'),
  });
},


controller.js

export default Ember.Controller.extend({
  personValue: '',
  init: function() {
    this.store.unloadAll('person');
  },
  actions: {
    //При фокусе на инпут поле имитирую нажатие кнопки btn-search, для раскрытия списка
    focusedCustomer: function(){
      //console.log('focusedCustomer');
      $('#btn-search').click();
    },
    //Ищу имя после ввода 3 символа, перед этим очищаю локальное дата хранилище для person
    handleFilterCustomer(){
      let filterInputValue = this.get('personValue');
if(filterInputValue.length<3){
//console.log('value<3',filterInputValue);
        this.store.unloadAll('person');
} else {
        this.store.unloadAll('person');
        this.get('store').query('person', { name: filterInputValue });
        //console.log('value>3',filterInputValue);
}
},
    //Выбор человека из списка
    customerClick(customer_name, customer_id){
      //Вставляю имя выбранного человека в инпут
      this.set("personValue", customer_name);
      //беру запись в хранилище
      let customer = this.store.peekRecord('person', customer_id);
      //и присваиваю к полю задачи
      this.set('model.task.customer', customer);
    },
  }
});

воскресенье, 18 декабря 2016 г.

Ember локализация

Для локализации Ember приложений я использую - ember-i18n

Установка
$ cd my-ember-project
$ ember install ember-i18n

Настройка

В config/environment.js устанавливаю русскую локализацию по умолчанию:
  var ENV = {
    ...
    i18n: {
      defaultLocale: 'ru'
    },
  ...
  }

Создание файла для русского перевода - ru

Запускаю команду генерации русской локализации, которая создаст файл app/locales/ru/translations.js - это словарь, в котором будет русский перевод:
$ ember generate locale ru


Перевод текста

1) Добавляю в словарь app/locales/ru/translations.js строку - "Contact":"Контакты",
export default {
  "Contact":"Контакт",
  ...
};
Открываю template.hbs и для слова "Contact" ставлю хелпер для перевода - {{t "Contact"}}
{{#link-to 'contact' tagName="li"}}<a href>{{t "Contact"}}</a>{{/link-to}}
2) Для использования хелпера перевода {{t }} внутри двойных фигурных скобок используется простые скобки, т.е.(t "contact"). Например, используется хелпер input и нужно сделать перевод текста в placeholder="Project name"
{{input type="text" value=model.project.name placeholder=(t "Project name")}}
и добавляю в словарь app/locales/ru/translations.js
export default {
  "Project name":"Название проекта",
  ...
};
3) Так же в хелпер {{t }} можно передать переменные. Например,
в темплейте:
{{t "The (model.user.name)'s project: '(model.project.name)'" username=model.user.name project=model.project.name}}

в translations.js
export default {
  "The (model.user.name)'s project: '(model.project.name)'": `Проект "{{project}}" пользователя {{username}}`
};
В translations.js для перевода использовались обратные кавычки, а "{{project}}" заключен в простые кавычки.

суббота, 17 декабря 2016 г.

Ember datetime picker



Установить и использовать этот ember datetime picker очень просто.

Установка

$ cd ember-project
$ ember install ember-datetimepicker

Использование

На сайте проекта просто нет никакого описания по использованию ember-datetimepicker. Но посмотрев исходники проекта, я обнаружил в тестах пример использования 
https://github.com/kellyselden/ember-datetimepicker/blob/master/tests/dummy/app/

{{date-time-picker
  datetime
  options=options
  action=(action action)
}}
<span class="text">
  {{datetime}}
</span>


А вот как сделал я в темлейте своего приложения привязав к полю модели model.task.date:

{{date-time-picker model.task.date action=(action (mut model.task.date)) }}

Немного пояснений:
  • date-time-picker - это хелпер ember-datetimepicker
  • аргумент первый: model.task.date - если это значение установлено, то дата будет сразу показана
  • аргумент второй: action=(action (mut model.task.date)) - присваивается дата, выбранная в пикере, в модель model.task.date
И это все, никаких обработок в route и controller делать не надо. Вот так вот, все проще некуда.


среда, 26 октября 2016 г.

Создание среды для разработки веб приложения под Django framework и Ember js

В этом howto будет расказано, каким образом создать среду для разработки веб приложения под Django framework и Ember js (DjEmber).
Права суперпользователя linux нужны только для того, чтобы установить Development Tools и node js, остальные процессы установки делаются под простым пользователем (в этом примере пользователь example).

I. Проект DjEmber - example.com
II. Проект Django - back
III. Проект Ember js - front

I. Проект DjEmber - example.com


- Пользователь - example
- Пользовательская директория /home/example/
- Проект DjEmber - example.com - будет размещаться в /home/example/Projects/example.com/
- Проект Django - back (от слова backend) - будет размещаться в /home/example/Projects/example.com/back/
- Проект Ember - front (от слова frontend) - будет размещаться в /home/example/Projects/example.com/front/
- В Django проекте - back - будет использоваться виртуальное окружение с Python версии 3
- Python 3, установленный из исходников, будет в /home/example/python3/
- Виртуальное окружение для Django проекта - back - /home/example/virtualenv/example.com
- Путь для загруженных программ - /home/example/Downloads/

1. Установка дополнительных программ

$ su -c 'yum groupinstall "Development Tools"'
$ sudo yum install wget

2. Создаю корневой каталог для проекта example.com

$ mkdir -p ~/Projects/example.com

Готовые файлы настроек можно посмотреть и скачать с https://github.com/hairetdin/djember

II. Проект Django - back


1. Установка Python 3 в домашнюю директорию пользователя /home/example/python3

- скачиваю исходники стабильной версии python 3, выбираю в https://www.python.org/downloads/source/

$ cd ~/Downloads/
$ wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tar.xz

- распаковываю

$ tar xvf Python-3.5.2.tar.xz

- собираю конфигурацию, указываю путь куда будет установен python3 - /home/example/python3/ и устанавливаю

$ cd Python-3.5.2/
$ $ ./configure --prefix=$HOME/python3
$ make
$ make install

- теперь python3 установлен в /home/example/python3/, проверяю

$ ~/python3/bin/python3 -V
Python 3.5.2

2. Создание виртуального окружения для проекта example.com - back (виртуальные окружения у меня находяться в ~/virtualenv)

$ cd ~
$ mkdir -p virtualenv
$ ~/python3/bin/pyvenv ~/virtualenv/example.com

- проверяю работу созданного виртуального окружения - virtualenv/example.com

$ source ~/virtualenv/example.com/bin/activate

в терминале должна появиться строка начинающаяся с - (example.com). Теперь запущу python и посмотрю версию

$ python -V
Python 3.5.2

- деактивация виртуального окружения:

$ deactivate


3. Установка python приложений в виртуальное окружение virtualenv/example.com

- Активирую виртуальное окружение и устанавливаю python приложения

$ source ~/virtualenv/example.com/bin/activate
$ pip install django
$ pip install djangorestframework
$ pip install djangorestframework-jwt
$ pip install django-filter
$ pip install django-cors-headers

Если не будете использовать django-filter, то ставить необязательно.


4. Создаю Django бакэнд проект для example.com

Виртуальное окружение virtualenv/example.com дожно быть активировано.

- перехожу в корень проекта example.com

$ cd ~/Projects/example.com/

- создаю проект back

$ django-admin startproject back

- проверяю созданные Django проект

$ cd ~/Projects/example.com/back/
$ python manage.py runserver

Смотрю в браузере http://127.0.0.1:8000/ - работает, показывает страницу приветствия - "Congratulations on your first Django-powered page."

Хорошо, останавливаю запущенный back проект - Ctrl+C

5. Делаю настройки для ранее установленных python приложений в ~/Projects/example.com/back/back/settings.py

Я для этого я использую редактор Atom, открываю на редактирование settings.py и вношу следующие изменения:

- в INSTALLED_APPS добавляю 'rest_framework' и 'corsheaders'

INSTALLED_APPS = (
   ...
   # external apps
   'rest_framework',
   'corsheaders',
)

- в MIDDLEWARE_CLASSES добавляю 'corsheaders.middleware.CorsMiddleware',

MIDDLEWARE_CLASSES = [
   ...
   'corsheaders.middleware.CorsMiddleware',
   'django.middleware.common.CommonMiddleware',
   ...
]

- добавляю новую конфигурацию для REST_FRAMEWORK

REST_FRAMEWORK = {
   'DEFAULT_PERMISSION_CLASSES': [
# разрешаю подключение к api всем, ограничивать подключения буду во view
'rest_framework.permissions.AllowAny',
   ],
   'DEFAULT_AUTHENTICATION_CLASSES': (
# аутентификацию делаю на уровне сессий (для прямых веб подключений) и с использованием token для фронтэнда
'rest_framework.authentication.SessionAuthentication',
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
   ),
   'PAGE_SIZE': 1000,
}

- для CORS разрешаю все запросы во время разработки (DEBUG = True, а значит получится и CORS_ORIGIN_ALLOW_ALL = True):

CORS_ORIGIN_ALLOW_ALL = DEBUG

- для djangorestframework-jwt (JSON Web Token) добавляю настройки:

JWT_AUTH = {
   'JWT_RESPONSE_PAYLOAD_HANDLER': 'back.views.jwt_response_payload_handler',
   'JWT_AUTH_HEADER_PREFIX': 'Bearer',
}

- настройки settings.py закончены, сохраняю.

6. Создаю ~/Projects/example.com/back/back/views.py, открываю на редактирование и добавляю функцию:

def jwt_response_payload_handler(token, user=None, request=None):
   return {
'access_token': token,
   }

Для чего нужна эта функция? Все дело в том, что djangorestframework-jwt, по умолчанию, при запросе ключа возвращает 'token': длинныйдлинныйключ. А ember-simple-auth хочет получить 'access_token': длинныйдлинныйключ , вот поэтому и необходимо сделать эту функцию.

7. В ~/Projects/example.com/back/back/urls.py добавляю api для аутентификации по ключу:

from rest_framework_jwt.views import obtain_jwt_token
#...

urlpatterns = patterns(
   '',
   # ...

   url(r'^api/auth/login/', obtain_jwt_token),
)

8. Делаю миграцию, создаю суперпользователя - admin, запускаю проект back

$ source ~/virtualenv/example.com/bin/activate
$ cd ~/Projects/example.com/back/
$ python manage.py migrate
$ python manage.py createsuperuser
$ python manage.py runserver

- Теперь через браузер проверяю аутентификацию по адресу http://127.0.0.1:8000/api/auth/login/ , после ввода логина и пароля и нажатии на кнопку "POST", должен появиться ключ - "access_token":"длинныйдлинныйключ".
- Не останавливая проект, запускаю новое терминальное окно и проверяю аутентификацию через утилиту командной строки - curl:

$ curl -X POST -d "username=admin&password=парольсуперпользователя" http://127.0.0.1:8000/api/auth/login/

В ответ должен вернуться - {"access_token":"длинныйдлинныйключ"} . Если все так, значит все настроено правильно.

- На этом настройка бакэнда закончена. Приступаю к запуску и настройке фронтэнда.


III. Проект Ember js - front


1. Создаю ember проект - example.com/front

$ cd ~/Projects/example.com
$ sudo npm install -g ember-cli
$ ember new front

2. Запускаю вновь созданный ember проект - front (команда "ember server" или, сокращенно, "ember s")

$ cd ~/Projects/example.com/front
$ ember s

- При запуске вылетает ошибка "Could not start watchman; falling back to NodeWatcher for file system events.", безопасно игнорируем ее как советует https://ember-cli.com/user-guide/#watchman. Хоть я и установил watchman по инструкции - https://facebook.github.io/watchman/docs/install.html, но при запуске команды "ember -v" под пользователем example получаю ошибку, а при запуске от root вышеприведенной ошибки нет. Если знаете как исправить - подскажите.

- смотрю в браузере http://localhost:4200/ - работает

3. Устанавливаю ember-django-adapter адаптер. front (ember) должен понимать как стучаться в back (django)

$ cd ~/Projects/example.com/front
$ ember install ember-django-adapter

- Добавляю в настройки фронтэнда строку - ENV.APP.API_HOST = 'http://localhost:8000';
Редактирую файл настроек Ember проекта: ~/Projects/example.com/front/config/environment.js

if (environment === 'development') {
 ENV.APP.API_HOST = 'http://localhost:8000';
 ...
}

 Т.е. при разработке, когда django проект back будет запущен командой "python manage.py runserver", ember проект front будет обращаться к http://localhost:8000/. Наименование api можно изменить допустим на my-api, подробности в документации http://dustinfarris.com/ember-django-adapter/ .

4. Устанавливаю аутентификацию для Ember фронэнда

$ cd ~/Projects/example.com/front
$ ember install ember-simple-auth


5. Создаю фронтэнд приложение - application

- Т.к. в Ember js, по умолчанию, роуты начинаются с приложения application, то и аутентификацию прилеплю на странице application (application хоть и не виден в главном router.js, но при запуске ember проекта сначала обрабатываются именно application). Простыми словами, application - это базовые настройки для Ember js проекта.
Я буду использовать привычный для Django порядок - каждое приложение складывается в отдельную папку, для этого используется в команде "ember generate" с дополнительным ключом "--pod". Команду "ember generate" можно сократить до "ember g".

- Создаю template, controller, adapter для application.

$ cd ~/Projects/example.com/front/
$ ember g route application --pod
$ ember g controller application --pod
$ ember g adapter application --pod

После выполнения этих команд во front/app создалась папка приложения - application и внутри нее файлы route.js, controller.js, adapter.js и template.hbs. Таким образом используя ключ --pod создалась отдельная папка apllication в которой разместились роут, контроллер, адаптер и темплейт. Для меня такая структура более приемлема, потому что в дальнейшем можно быстро копировать приложения в другие проекты.


6. Редактирую темплейт app/application/template.hbs, добавляю:

{{!-- app/application/template.hbs --}}
<div class="menu">
 {{#if session.isAuthenticated}}
   <a href {{action 'invalidateSession'}}>Выход</a>
 {{else}}
   {{#link-to 'login'}}Вход{{/link-to}}
 {{/if}}
</div>
<div class="main">
 {{outlet}}
</div>

Таким образом, для "Выход" навешиваю действие - action 'invalidateSession',а для "Вход" ссылку переход на страницу login - #link-to 'login'. Строка {{outlet}} показывает, что весь вышеприведенный код созданного темплейта application будет наследоваться нижестоящими темплейтами, т.е всеми остальными темплейтами, которые будут созданы в проекте.

7. Редактирую контроллер app/application/controller.js, внедряю в проект сессии и создаю action(действие) - invalidateSession():

// app/application/controller.js
import Ember from 'ember';

export default Ember.Controller.extend({
 session: Ember.inject.service('session'),

 actions: {
   invalidateSession() {
     this.get('session').invalidate();
   }
 }
});

8. Добавляю аутентификацию в applicaton route

- Сервис сессий имеет события authenticationSucceeded и invalidationSucceeded, которые показывают прошла аутентификация или нет. Чтобы эти события были доступны в сесии на всех страницах сайта добавляю в app/application/route.js:

// app/application/route.js
import Ember from 'ember';
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';

export default Ember.Route.extend(ApplicationRouteMixin);

9. Добавляю authorizer(авторизатор) в adapter

- после того как аутентификация будет успешно выполнена, для повторного доступа к веб api бакэнда нужен авторизатор. Т.к. адаптер я использую уже готовый - ember-django-adapter, то в application я его расширю указав на авторизатор 'authorizer:oauth2', который создам далее. А пока редактирую app/application/adapter.js :

// app/application/adapter.js
import DRFAdapter from '../adapters/drf';
import DataAdapterMixin from 'ember-simple-auth/mixins/data-adapter-mixin';

export default DRFAdapter.extend(DataAdapterMixin , {
 authorizer: 'authorizer:oauth2'
});

10. Создаю аутентификатор и авторизатор oauth2

$ cd ~/Projects/example.com/front/
$ ember g authenticator oauth2
$ ember g authorizer oauth2

- редактирую app/authenticators/oauth2.js (использую стандартную аутентификацию OAuth2PasswordGrant из ember-simple-auth)

// app/authenticators/oauth2.js
import OAuth2PasswordGrant from 'ember-simple-auth/authenticators/oauth2-password-grant';

export default OAuth2PasswordGrant.extend({

 serverTokenEndpoint: 'http://127.0.0.1:8000/api/auth/login/',

});


- редактирую app/authorizers/oauth2.js (использую стандартный авторизатор - OAuth2Bearer из ember-simple-auth)

// app/authorizers/oauth2.js
import OAuth2Bearer from 'ember-simple-auth/authorizers/oauth2-bearer';

export default OAuth2Bearer.extend();


11. Приложение login

В app/application/template.hbs я указал использовать для "Вход" переход на login страницу.

- Для приложение login создаю route, controller (template создается автоматом при создании route):

$ cd ~/Projects/example.com/front/
$ ember g route login --pod
$ ember g controller login --pod

При создании роута для login в основном роуте проекта - app/router.js - добавились строки для маршрутизации login приложения:

Router.map(function() {
 this.route('login');
});

теперь проект front знает о приложении login.

- Создаю логин форму, редактирую app/login/template.hbs:

{{!-- app/login/template.hbs --}}
<form {{action 'authenticate' on='submit'}}>
 <label for="identification">Login</label>
 {{input id='identification' placeholder='Enter Login' value=identification}}
 <label for="password">Password</label>
 {{input id='password' placeholder='Enter Password' type='password' value=password}}
 <button type="submit">Вход</button>
 {{#if errorMessage}}
   <p>{{errorMessage}}</p>
 {{/if}}
</form>

У этой формы имеется действие (action) - {{action 'authenticate' on='submit'}} - при нажатии на кнопку "Вход".

- Описываю в login контроллере действие authenticate() при нажатии на кнопку "Вход" (так как при аутентификации используются сессия, то надо и ее объявить через переменную session), редактирую app/login/controller.js:

// app/login/controller.js
import Ember from 'ember';

export default Ember.Controller.extend({
 session: Ember.inject.service('session'),

 actions: {
   authenticate() {
     let { identification, password } = this.getProperties('identification', 'password');
     this.get('session').authenticate('authenticator:oauth2', identification, password).
then(() => {
 console.log('Success! authenticated with token: ' + this.get('session.data.authenticated.access_token'));
}, (err) => {
 alert('Error obtaining token: ' + err.responseText);
}).
catch((reason) => {
this.set('errorMessage', reason.error || reason);
     });
   }
 }
});


При выполнении authenticate() получаем логин и пароль из формы, затем для session выполняем метод authenticate, для которого в качестве аргументов передаем ранее созданный authenticator:oauth2, а также логин и пароль.


- На этом настройка ember js фронтэнда - example.com/front завершена.


Проверяю работу среды разработки DjEmber для example.com

- запускаю бакэнд в 1 терминальном окне

$ source ~/virtualenv/example.com/bin/activate
$ cd ~/Projects/example.com/back/
$ python manage.py runserver


- запускаю фронтэнд во 2 терминальном окне

$ cd ~/Projects/example.com/front/
$ ember s

- запускаю Google Chrome, открываю http://localhost:4200/, запускаю консоль - F12 -> Console.
- нажимаю кнопку вход, ввожу login и password (использую пользователя суперюзер созданного в Django back), нажимаю вход и смотрю в консоль, появилось сообщение:

Success! authenticated with token: длинныйдлинныйключ

DjEmber окружение для разработки готово. Теперь можно создавать api на бакэнде под django-rest-framework и подключаться к нему из ember фронтэнда.
Удачных вам проектов!!!

пятница, 14 октября 2016 г.

Django аутентификация через NGINX kerberos (Active Directory)

В корпоративном сегменте часто используют Windows Active Directory. В Active Directory имеются учетные данные пользователей (логин, пароль) и почему бы не использовать эти учетные данные для аутентификации в Django? Как модно сейчас выражаться - Single Sign On (SSO) - один раз прошел аутентификацию и пользуйся сервисами, т.е пользователь прошел доменную аутентификацию при входе в систему Windows и может пользоваться ресурсами сети без повторного ввода логина и пароля. Django поддерживает эту возможность - метод аутентификации с использованием REMOTE_USER, который описан в официальной документации Django  - https://docs.djangoproject.com/en/dev/howto/auth-remote-user/

Если просто описать Windows аутентификацию пользователя в Django, то получится следующее:
- пользователь под доменным именем входит в Windows, открывает браузер, вводит адрес сайта example.com и нажимает Enter;
- NGINX получает запрос на выдачу сайта example.com, распознает пользователя через модуль керберос, создает переменную REMOTE_USER и передает Django проекту;
- Django проект видит в запросе REMOTE_USER и использует его для аутентификации. Если django не обнаруживает REMOTE_USER, то аутентификация не состоялась.

Windows аутентификация работает по умолчанию для браузера Internet Explorer, для Firefox и Chrom надо настраивать (ключевые слова для поиска - chrome kerberos authentication windows).

Реализации прозрачной Django аутентификации в домене Windows 

Нужно выполнить следующие шаги:

- Настроить NGINX с поддержкой kerberos. Как это реализуется, можно посмотреть здесь - Установка NGINX kerberos на centos 7.

- Настроить запуск Django через NGINX. Как это реализуется, можно посмотреть здесь - Запуск NGINX Django python3 на сервере Centos 7

- Добавить удаленную аутентификацию для Django. Как это реализовать смотрите ниже.



1. Аутентификация kerberos для сайта example.com


Использую:
- django проект - /home/example/Projects/example.com/back
- сокет - /run/uwsgi/example.sock, который запускается конфигурацией вассала /etc/uwsgi/vassals/enabled/example.ini

- Изменяю конфигурация nginx для сервера example.com:

$ sudo vi /etc/nginx/conf.d/example.com.conf

# Конфигурация для сервера example.com,
# с uwsgi сокетом для django проекта /home/example/Projects/example.com/back

server {
listen  8888;
server_name example.com;

location /static/ {
root /home/example/Projects/example.com;
}

location /media/ {
root /home/example/Projects/example.com;
    }

location /  {
# подгружаю django сайт
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/example.sock;

# передаю для django REMOTE_USER
uwsgi_param REMOTE_USER $remote_user;

# аутентификация kerberos

auth_gss on;
auth_gss_realm EXAMPLE.COM;
auth_gss_keytab /etc/example.keytab;
auth_gss_service_name HTTP/example.com;

# выключает basic аутентификация
# auth_gss_allow_basic_fallback off;
}
}


Я оставил basic аутентификацию для того чтобы заходить с компьютеров не включенных в домен. Но обязательно нужно сделать https подключение, потому что логин и пароль передаются в открытом виде.

- Проверяю конфигурацию nginx:

$ sudo nginx -t

Если ошибок нет, то

- Перезапускаю сервис nginx

$ sudo service nginx restart

- Смотрю с Windows компьютера под доменным пользователем через Internet Explorer на http://example.com:8888/ , страница django проекта загружается, в логах /etc/nginx/access.log имеется запись с аутентификацией под доменным пользователем

2. Аутентификация в Django через NGINX


- Для аутентификации через REMOTE_USER, который будет браться после аутентификации пользователя при входе на сайт (nginx), вношу изменения в /home/example/Projects/example.com/back/back/settings.py

MIDDLEWARE = [
   '...',
   'django.contrib.auth.middleware.AuthenticationMiddleware',
   'django.contrib.auth.middleware.RemoteUserMiddleware',
   '...',
]

AUTHENTICATION_BACKENDS = [
   'django.contrib.auth.backends.RemoteUserBackend',
]


!!! Строка 'django.contrib.auth.middleware.RemoteUserMiddleware' должна обязательно следовать после 'django.contrib.auth.middleware.AuthenticationMiddleware'

- Если по какой то причине nginx аутентификация не пойдет (например, не доступен контроллер домена), то django проект не получит REMOTE_USER и аутентификация не пройдет и все попытки войти в админку сайта будут безрезультатны (даже под superuser). Поэтому, на всякий случай, надо добавить стандартную Django аутентификацию в settings.py

AUTHENTICATION_BACKENDS = [
   'django.contrib.auth.backends.RemoteUserBackend',
   'django.contrib.auth.backends.ModelBackend',
]


- Перезапускаю сервис uwsgi

$ sudo service uwsgi restart

- Захожу через браузер http://example.com:8888/admin с Windows компьютера под доменным пользователем и ... не надо вводить логин и пароль, прозрачная аутентификация сработала.

Теперь при входе на сайт доменного пользователя учетная запись пользователя будет создана в базе Django проекта автоматически.

Запуск NGINX Django python3 на сервере Centos 7


Что и где будет располагаться


Название сайта: example.com
Корень сайта: /home/example/Projects/example.com
Статика сайта (css, js и т.п): /home/example/Projects/example.com/static
Медиа файлы сайта: /home/example/Projects/example.com/media
Django проект для сайта: /home/example/Projects/example.com/back
Пользовательский каталог: /home/example/
Виртуальное окружение (python3) для Django проекта: /home/exam/virtualenv/example.com/
Конфигурация NGINX для сайта: /etc/nginx/conf.d/example.com.conf
Конфигурация uWSGI сервиса в режиме императора: /etc/systemd/system/uwsgi.service, смотрит конфигурации вассалов в каталоге /etc/uwsgi/vassals/enabled/
Вассал uWSGI для запуска Django проекта: /etc/uwsgi/vassals/enabled/example.ini
Сокет uWSGI, создается при удачном запуске вассала: /run/uwsgi/example.sock
Перезапуск вассала uWSGI, когда нужно внести изменения на сайте после внесения изменений в Django проекте: нужно переместить /etc/uwsgi/vassals/enabled/example.ini /etc/uwsgi/vassals/disabled/ для отключения. Для запуска, переместить обратно в /etc/uwsgi/vassals/enabled/.

Сервисы NGINX и uWSGI запускаются под пользователем nginx.

!Если будут проблемы при запуске сервисов с правами доступа к пользовательскому каталогу, то можно временно отключить SELINUX:
# setenforce 0

1. Виртуальное окружение для Django проекта 

- все виртуальные окружения у меня храняться в ~/virtualenv
- в пользовательском каталоге установлен из исходников ~/python3, его я буду использовать в виртуально окружении
- я взял за правило создавать виртуальное окружение для каждого нового Django проекта (для разных проектов используются разные версии Python, Django и другие python библиотеки)

- создаю виртуальное окружение example.com в директории /home/exam/virtualenv , использую python 3 версии

$ cd ~/virtualenv/
$ virtualenv -p ~/python3/bin/python3 example.com

- запускаю созданное виртуальное окружение

$ source ~/virtualenv/example.com/bin/activate

- проверяю версию python для созданного виртуального окружения

$ python -V
Python 3.5.1
все как и задумывалось

- Устанавливаю django в виртуальном окружении example.com

$ pip install django


2. Создание Django проекта 

Все веб проекты у меня лежат в ~/Projects

$ source ~/virtualenv/example.com/bin/activate
$ cd ~/Projects/

- создаю каталог в котором у меня будет размещаться сайт

$ mkdir example.com

- перехожу в каталог проекта и создаю каталоги для медиа и статики

$ cd example.com/
$ mkdir media
$ mkdir static

- создаю django проект (Django проекты я создаю с названием back, от слова backend, а frontend размещаю в каталоге front)

$ django-admin startproject back

- редактирую пути для статики и медиа в созданном Django проекте

$ vi ~/Projects/example.com/back/back/settings.py

STATIC_URL = '/static/'
STATIC_ROOT = '/home/example/Projects/example.com/static'

MEDIA_URL = '/media/'
MEDIA_ROOT = '/home/example/Projects/example.com/media'

- проверяю работу созданного Django проекта, предварительно делаю миграцию, собираю статику и создаю суперпользователя

$ cd ~/Projects/example.com/back/
$ python manage.py migrate
$ python manage.py collectstatic
$ python manage.py createsuperuser
$ python manage.py runserver

Смотрю в браузере http://127.0.0.1:8000 и http://127.0.0.1:8000/admin/
Все работает, мой Django проект запустился

- деактивирую виртуальное окружение
$ deactivate


3. Запуск uWSGI для Django проекта



- Устанавливаю в системе uwsgi

$ sudo pip install uwsgi

 - Создаю файл /home/example/Projects/example.com/back/back.wsgi

import os
#back - это название проекта откуда будут грузится настройки !!!
os.environ['DJANGO_SETTINGS_MODULE'] = 'back.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()


- Запускаю тест uwsgi на порту 8080 с --pythonpath /home/example/virtualenv/example.com/lib/python3.5/site-packages и с указанием проекта  --chdir /home/example/Projects/example.com/back. Ключи, с которыми сейчас запистится uwsgi я буду использовать в настройках.

$ uwsgi --http :8080 --pythonpath /home/example/virtualenv/example.com/lib/python3.5/site-packages --chdir /home/example/Projects/example.com/back --module back.wsgi

В браузере, по адресу http://127.0.0.1:8080/, снова вижу страницу созданного Django проекта
http://127.0.0.1:8080/admin отображается без статики, но пока об этом не стоит беспокоится, настроится позже.

!!! Внимание. В некоторых инструкциях написано использование ключа --home, --virtualenv, -H или --venv, который, якобы, используется для пути к python в виртуальном окружении, так работает только если и в системе и виртуально окружении стоит python2! В моем случае используется python3, который установлен в виртуальном окружении, поэтому нужно использовать ключ --pythonpath путь_до_виртуального_окружения/lib/python3.5/site-packages


4. Запуск uWSGI в режиме императора

Когда имеется несколько сайтов с uwsgi, то лучше запускать uwsgi в режиме императора. Хотя, у меня пока только один сайт, но лучше сразу сделаю настройки для нескольких сайтов, чтобы не возращаться к этой теме.

- Настройки для запуска wsgi сайтов будут храниться в /etc/uwsgi/vassals, создаю эту папку

$ sudo mkdir -p /etc/uwsgi/vassals

- Запущенные вассалы будут распологаться в директории enabled, а отключенные я буду размещать в disabled. Создаю для них папки

$ sudo mkdir /etc/uwsgi/vassals/enabled
$ sudo mkdir /etc/uwsgi/vassals/disabled

- Создаю uwsgi ini файл с настройками для моего Django проекта

$ sudo vi /etc/uwsgi/vassals/disabled/example.ini

[uwsgi]
chdir = /home/example/Projects/example.com/back
pythonpath = /home/example/virtualenv/example.com/lib/python3.5/site-packages
socket = /run/uwsgi/example.sock
module = back.wsgi

chown-socket = nginx:nginx
chmod-socket = 660
master = true
processes = 2
threads = 2
vacuum = true

- Для проверки созданных настроек, запускаю uwsgi c настройками /etc/uwsgi/vassals/disabled/example.ini

$ uwsgi --ini /etc/uwsgi/vassals/disabled/example.ini

Чтобы пользователь nginx мог читать настройки из каталога проектов /home/example/Projects,
- добавляю пользователя nginx в группу example

$ usermod -a -G example nginx

-и изменяю права доступа на домашнюю директорию пользователя (именно на домашнюю, а не только на каталог корня сайта)

$ chmod 710 /home/example

- Создаю сервис для запуска uwsgi, для императора указываю смотреть каталог /etc/uwsgi/vassals/enabled (uwsgi будет запускаться под пользователем nginx, запущенные сервисы будут размещаться в /run/uwsgi

$ vi /etc/systemd/system/uwsgi.service

[Unit]
Description=uWSGI Emperor service

[Service]
ExecStartPre=/usr/bin/bash -c 'mkdir -p /run/uwsgi; chown nginx:nginx /run/uwsgi'
ExecStart=/usr/bin/uwsgi --emperor /etc/uwsgi/vassals/enabled --uid nginx --gid nginx
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

[Install]
WantedBy=multi-user.target

- Запускаю сервис uwsgi

$ sudo systemctl start uwsgi

- Перемещаю вассал example.ini в enabled для запуска (вассалы, согласно настройкам /etc/systemd/system/uwsgi.service просматриваются в каталоге enabled)

$ mv /etc/uwsgi/vassals/disabled/example.ini /etc/uwsgi/vassals/enabled/

Теперь вассал должен быть обнаружен в этом каталоге и обработан.
Если в дальнейшем я захочу приостановить работу сайта, то просто перемещаю файл example.ini из enabled в disabled.

- Смотрю логи, запустился ли вассал для example.com

$ sudo cat /var/log/messages

Сервис uwsgi работает в режиме иператора и вассал example.ini ожидает запросов -
[emperor] vassal example.ini is ready to accept requests.

- Теперь можно добавить запуск uwsgi в запуск при загрузке системы.

$ sudo systemctl enable uwsgi


5. Настраиваю nginx для работы Django сайта


У меня уже установлен NGINX. Если нужны подробности установки, то можно посмотреть http://hairetdin.blogspot.ru/2016/10/nginx-kerberos-centos-7.html

Конфигурационные файлы для сайтов, согласно настройкам /etc/nginx/nginx.conf (include /etc/nginx/conf.d/*.conf;), я размещаю в /etc/nginx/conf.d/

- Создаю конфигурацию nginx для сайта example.com

$ sudo vi /etc/nginx/conf.d/example.com.conf

server {
   listen 80;
   server_name example.com www.example.com;

   location = favicon.ico { access_log off; log_not_found off; }
   location /static/ {
root /home/example/Projects/example.com;
   }

   location /media/ {
root /home/example/Projects/example.com;
   }

   location / {
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/example.sock;
   }
}

В этом файле я указал где смотреть статику и медиа файлы для моего проекта, а также, где смотреть параметры uwsgi.

- Тестирую созданную конфигурацию:

$ nginx -t

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Конфигурация в порядке.

- Перезапускаю сервис nginx

$ sudo systemctl restart nginx

- По умолчанию в Django проекте используется sqlite база данных. Ранее пользователя nginx (под которым запускается сервисы NGINX и uWSGI) я уже добавил в группу example, теперь добавлю права на запись группе для файла базы данных - db.sqlite3:

 $ chmod 664 /home/example/Projects/example.com/back/db.sqlite3

- Добавляю в /etc/hosts домен example.com, чтобы можно было проверить работу локально

$ sudo /etc/hosts

192.168.1.3 example.com

- Смотрю сайт example.com через браузер
Все работает

четверг, 13 октября 2016 г.

Установка NGINX kerberos на centos 7.



I. Установка nginx с модулем kerberos.


под su

1. Устанавливаю nginx (чтобы не изобретать настройки для nginx, возьмем их из стандартной установки)

# yum install nginx

2. Устанавливаю пакеты необходимые для сборки из исходников

# yum install gcc-c++ pcre-devel zlib-devel make wget openssl-devel libxml2-devel libxslt-devel gd-devel perl-ExtUtils-Embed GeoIP-devel gperftools-devel

3. Смотрим настройки с которыми установился NGINX

# nginx -V

nginx version: nginx/1.10.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC)
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'


4. Скачиваю исходники NGINX и распаковываю

$ wget http://nginx.org/download/nginx-1.10.1.tar.gz
$ tar zxvf nginx-1.10.1.tar.gz


5. Перехожу в каталог исходников nginx

$ cd nginx-1.10.1/

6. Скачиваю Nginx module for HTTP SPNEGO auth (модуль для аутентификации kerberos)

# git clone https://github.com/stnoonan/spnego-http-auth-nginx-module

7. Останавливаю nginx

# service nginx stop

8. Собираю и устанавливаю nginx с ранее просмотренными настройками и добавляю --add-module=spnego-http-auth-nginx-module

$ ./configure --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E' --add-module=spnego-http-auth-nginx-module

# make

# make install

9. Запускаю nginx и смотрю результат в браузере по адресу http://127.0.0.1/

# service nginx start



II. Настройка kerberos на Centos для подключения к Active directory


1. Проверяю пингуется ли контролер домена (test.example.com) по имени (у меня контролер домена на Windows 2012). Если не пингуется, надо прописать в качестве dns сервер контролер домена.

# ping test.example.com

2. Устанавливаю пакет для тестирования работы kerberos на centos

# yum install krb5-workstation

3. Настраиваю kerbereros путем редактивания /etc/krb5.conf. Вместо example.com подставить свой домен (!!!где написан EXAMPLE.COM большими буквами там обязательно надо свой домен написать большими буквами). Контролер домена у меня имеет ip - 192.168.1.10 (вам надо заменить).

    [logging]
     default = FILE:/var/log/krb5libs.log
     kdc = FILE:/var/log/krb5kdc.log
     admin_server = FILE:/var/log/kadmind.log
   
    [libdefaults]
     dns_lookup_realm = false
     ticket_lifetime = 24h
     renew_lifetime = 7d
     forwardable = true
     rdns = false
     default_realm = EXAMPLE.COM
     default_ccache_name = KEYRING:persistent:%{uid}

    [realms]
     EXAMPLE.COM = {
      kdc = 192.168.1.10
      admin_server = 192.168.1.10
     }

    [domain_realm]
     .example.com = EXAMPLE.COM
     example.com = EXAMPLE.COM

4. Проверяю работы kerberos путем подключения под доменным пользователем. Я создал пользователя на контролере домена - testuser.

# kinit testuser@EXAMPLE.COM
Password for testuser@EXAMPLE.COM: Ввожу пароль для testuser

- смотрю созданный тикет

# klist

Ticket cache: KEYRING:persistent:0:0
Default principal: testuser@EXAMPLE.COM

Valid starting       Expires              Service principal
10/10/2016 09:35:01  10/10/2016 19:35:01  krbtgt/EXAMPLE.COM@EXAMPLE.COM
renew until 10/17/2016 09:34:55

- удаляю созданный тикет (проверил, работает, больше этот тикет не нужен)
# kdestroy

5. На контролере домена (windows):
5.1 Создаю учетную запись компьютера - srv-nginx (В active directory пользователи и компьютеры -> в домене example.com -> компьютеры -> создать компьютер srv-nginx). Пользователя с именем srv-nginx не должно быть в этом домене
5.2 Создаю ключ keytab, выполняю команду

ktpass -princ HTTP/srv-nginx.example.com@EXAMPLE.COM -mapuser srv-nginx$@EXAMPLE.COM -crypto ALL -ptype KRB5_NT_SRV_HST +rndpass -out d:\srv-nginx.keytab

появится сообщение, которое предупреждает о создание нового пароля для моего компьютера SRV-NGINX$ - соглашаемся - y:
Reset SRV-NGINX$'s password [y/n]? y

- небольшие пояснения: srv-nginx$@EXAMPLE.COM - имя компьютера в актив директори (именно с $); +rndpass - пароль, который будет сгенерирован для учетной записи компьютера, где домен написан большими буквами пишем большими буквами.

- если все прошло удачно, то ключик появится на диске - d:\srv-nginx.keytab

!!! Eсли вы до этого пытались создать ключ - keytab и использовали какие-то учетную запись и пароль и у вас ничего не получилось, то бросьте эту учетку и создайте новую ранее не использованную, любую, запись компьютера в актив директори. Не обязательно использовать для keytab имя имеющегося комьютера (имя файла вообще может быть какое угодно) или имеющегося пользователя, как в моем примере srv-nginx.example.com, я его потом заменил на portal. Я создал имя компьютера portal в актив директори, которого вообще не существует в сети, и сгенерил для него keytab и все прекрасно работает, главное чтобы была отработана привязка -princ HTTP/имя_компьютера.домен.ру@ДОМЕН.РУ -mapuser имя_компьютера$@ДОМЕН.РУ
Создать ключ keytab с правильным именем у меня так и не получилось, пришлось менять название веб сервера на portal. Видать где-то еще какая-то привязка есть, если кто знает - подскажите (по всей видимиости я что-то перемудрил на начально этапе).

- Проверить привязку spn (service principal name) к учетной записи компьютера можно используя команду windows:

setspn -Q HTTP/srv-nginx.example.com

Если HTTP/srv-nginx.example.com привязана к нескольким компьютерам или пользователям, то аутентификация кербероз работать не будет.
(для любителей покапаться в могзах актив директори могу посоветовать зайти в редактор атрибутов учетной записи созданного компьютера и там увидеть все своими глазами)

6. Копирую созданный ключ srv-nginx.keytab на srv-nginx в /etc/ (можно использовать winscp)

7. Проверяю ключ в работе:

# ktutil
ktutil:  rkt /etc/srv-nginx.keytab
ktutil:  list
slot KVNO Principal
---- ---- ---------------------------------------------------------------------
  1    4                   HTTP/srv-nginx.example.com@EXAMPLE.COM
  2    4                   HTTP/srv-nginx.example.com@EXAMPLE.COM
  3    4                   HTTP/srv-nginx.example.com@EXAMPLE.COM
  4    4                   HTTP/srv-nginx.example.com@EXAMPLE.COM
  5    4                   HTTP/srv-nginx.example.com@EXAMPLE.COM
ktutil:  q

или

# klist -ke /etc/srv-nginx.keytab
Keytab name: FILE:/etc/srv-nginx.keytab
KVNO Principal
---- --------------------------------------------------------------------------
  4 HTTP/srv-nginx.example.com@EXAMPLE.COM (des-cbc-crc)
  4 HTTP/srv-nginx.example.com@EXAMPLE.COM (des-cbc-md5)
  4 HTTP/srv-nginx.example.com@EXAMPLE.COM (arcfour-hmac)
  4 HTTP/srv-nginx.example.com@EXAMPLE.COM (aes256-cts-hmac-sha1-96)
  4 HTTP/srv-nginx.example.com@EXAMPLE.COM (aes128-cts-hmac-sha1-96)


затем проверяю работу ключа

# kinit -kt /etc/srv-nginx.keytab HTTP/srv-nginx.example.com@EXAMPLE.COM

# kvno HTTP/srv-nginx.example.com@EXAMPLE.COM
HTTP/srv-nginx.example.com@EXAMPLE.COM: kvno = 3

# klist -e
Ticket cache: KEYRING:persistent:0:0
Default principal: HTTP/srv-nginx.example.com@EXAMPLE.COM

Valid starting       Expires              Service principal
10/10/2016 15:30:34  10/11/2016 01:22:04  HTTP/srv-nginx.example.com@EXAMPLE.COM
renew until 10/17/2016 15:22:03, Etype (skey, tkt): arcfour-hmac, arcfour-hmac
10/10/2016 15:22:04  10/11/2016 01:22:04  krbtgt/EXAMPLE.COM@EXAMPLE.COM
renew until 10/17/2016 15:22:03, Etype (skey, tkt): aes256-cts-hmac-sha1-96, arcfour-hmac

Убиваю ключ в памяти компьютера (сам ключ /etc/srv-nginx.keytab на диске остается :) )

# kdestroy

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


III. Конфигурация NGINX для работы с kerberos


1. Для тестирования добавляю в файервол порт 8888

- смотрю в файерволе что открыто

# firewall-cmd --permanent --list-all
public (default)
 interfaces:
 sources:
 services: dhcpv6-client ipp ipp-client mdns ssh
 ports:
 masquerade: no
 forward-ports:
 icmp-blocks:
 rich rules:

- Попутно удаляю неиспользуемый dhcpv6 (я использую в локалке ip v4)

# firewall-cmd --permanent --zone=public --remove-service=dhcpv6-client

- Добавляю порт tcp 8888

# firewall-cmd --permanent --zone=public --add-port=8888/tcp
success

- Перезагружаю файервол

# firewall-cmd --reload
success

2. Прописываю настройки nginx для сервера srv-nginx.example.com
 - Основной конфиг /etc/nginx/nginx.conf ссылается (include /etc/nginx/conf.d/*.conf;) на папку /etc/nginx/conf.d/ для дополнительных конфигов, там я и сделаю конфиг srv-nginx.example.com.conf

 - Создаю и редактирую файл конфигурации

# vi /etc/nginx/conf.d/srv-nginx.example.com.conf
server {
listen  8888; #слушает на порту tcp 8888
server_name srv-nginx.example.com

# аутентификация kerberos
location /  {
#       proxy_pass http://********/$request_uri;
# proxy_set_header   X-Real-IP $remote_addr;
# proxy_set_header   Host $http_host;
# proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;

auth_gss on;
auth_gss_realm EXAMPLE.COM;
auth_gss_keytab /etc/srv-nginx.keytab;
auth_gss_service_name HTTP/srv-nginx.example.com;

# выключает basic аутентификация, рекомендуется использовать off если нет https подключения
# auth_gss_allow_basic_fallback off;
}
}

 - Проверяю правильность написания конфигурации nginx:

# nginx -t

nginx: [emerg] directive "server_name" is not terminated by ";" in /etc/nginx/conf.d/srv-nginx.example.com.conf.conf:6
nginx: configuration file /etc/nginx/nginx.conf test failed

 Забыл поставить точку с запятой после server_name srv-nginx.example.com
 Правлю /etc/nginx/conf.d/srv-nginx.example.com.conf и снова тестирую

# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

 - Вот теперь перезапускаю сервер nginx. Хотя, если у вас не боевой сервер, то можно и сразу перезапустить и получить ошибку. А на рабочем останов веб сервера чреват громким шумом пользователей :).


3. Отладка nginx kerberos
 - Запущен ли сервер на порту 8888 можно посмотреть командой

# netstat -na |grep 8888

 - Логи nginx по умолчанию складываются в /var/log/nginx/, есть access.log error.log (доступны только для root)

 - Заходим на windows компьютер под доменным пользователем, запускаем internet explorer, заходим в свойства -> Безопасность -> Местная интрасеть -> Сайты -> Дополнительно -> Добавить в зону следующий узел - *.example.com -> Добавить -> Закрыть. Затем  набираем http://srv-nginx.example.com:8888 и видим страницу по умолчанию из корня сайта (вход выполнен под доменным пользователем)

 - Чтобы убедится в правильности входа, на сервере смотрим логи /var/log/nginx/access.log и видим ip_адрес и логин_пользователя (с виндовз компьютера)

Всёёёёёёёёёё

django-oscar tinymce 4 filebrowser

Задача: в дашборде django-oscar загружать изображения 1. Установка django-filebrowser-no-grappelli - Открываем проект, загружаем виртуа...