21 changed files with 441 additions and 289 deletions
-
1.gitignore
-
2README.md
-
0agent/downloader.py
-
0agent/monitoring_agent.py
-
0agent/netflow/netflow_handler.py
-
0agent/netflow/start_netflow.sh
-
0devapp/expect_scripts/dlink_DGS1100_reboot.exp
-
0devapp/expect_scripts/f601.py
-
0dhcp_lever.py
-
210dialing.py
-
31djing/local_settings.py.example
-
0docs/ats.md
-
310docs/install_debian.md
-
74docs/install_fedora.md
-
13install/djing.ini
-
37install/install_debian.sh
-
42install/nginx_server.conf
-
4install/robots.txt
-
0manage.py
-
0periodic.py
-
6requirements.txt
@ -1,210 +0,0 @@ |
|||||
#!/usr/bin/env python3 |
|
||||
from typing import Dict, Optional, AnyStr |
|
||||
import re |
|
||||
import signal |
|
||||
from time import sleep |
|
||||
from urllib.parse import urlencode |
|
||||
from urllib.request import urlopen |
|
||||
from urllib.error import HTTPError |
|
||||
from hashlib import sha256 |
|
||||
|
|
||||
from pid.decorator import pidfile |
|
||||
from djing.lib.messaging.sms import SmsSubmit, SmsDeliver |
|
||||
from asterisk import manager as ast_mngr |
|
||||
|
|
||||
|
|
||||
ASTERISK_MANAGER_AUTH = { |
|
||||
'username': 'admin', |
|
||||
'password': 'password', |
|
||||
'host': '127.0.0.1' |
|
||||
} |
|
||||
|
|
||||
API_AUTH_SECRET = 'your api secret' |
|
||||
SERVER_DOMAIN = 'http://localhost:8000' |
|
||||
|
|
||||
outbox_messages = False |
|
||||
|
|
||||
|
|
||||
def calc_hash(data): |
|
||||
if type(data) is str: |
|
||||
result_data = data.encode('utf-8') |
|
||||
else: |
|
||||
result_data = bytes(data) |
|
||||
return sha256(result_data).hexdigest() |
|
||||
|
|
||||
|
|
||||
def secure_request(data: Dict) -> Optional[AnyStr]: |
|
||||
vars_to_hash = [str(v) for v in data.values()] |
|
||||
vars_to_hash.sort() |
|
||||
vars_to_hash.append(API_AUTH_SECRET) |
|
||||
sign = calc_hash('_'.join(vars_to_hash)) |
|
||||
data.update({'sign': sign}) |
|
||||
try: |
|
||||
with urlopen("%s/dialing/api/sms/?%s" % (SERVER_DOMAIN, urlencode(data))) as r: |
|
||||
return r.read() |
|
||||
except ConnectionRefusedError: |
|
||||
print('ERROR: connection refused') |
|
||||
except HTTPError as e: |
|
||||
print('ERROR:', e) |
|
||||
|
|
||||
|
|
||||
class SMS(object): |
|
||||
def __init__(self, text, who, dev): |
|
||||
self.text = text |
|
||||
self.who = who |
|
||||
self.dev = dev |
|
||||
|
|
||||
def __add__(self, other): |
|
||||
if not isinstance(other, SMS): |
|
||||
raise TypeError |
|
||||
if self.who == other.who and self.dev == other.dev: |
|
||||
self.text += other.text |
|
||||
return self |
|
||||
|
|
||||
def __str__(self): |
|
||||
return "%s: %s" % (self.who, self.text) |
|
||||
|
|
||||
|
|
||||
class ChunkedMsg(object): |
|
||||
def __init__(self, sms_count, ref, sms): |
|
||||
self.sms_count = sms_count |
|
||||
self.ref = ref |
|
||||
self.sms = sms |
|
||||
|
|
||||
|
|
||||
class MyAstManager(ast_mngr.Manager): |
|
||||
sms_chunks = list() |
|
||||
|
|
||||
def new_chunked_sms(self, count, ref, sms): |
|
||||
msg = ChunkedMsg(count, ref, sms) |
|
||||
self.sms_chunks.append(msg) |
|
||||
|
|
||||
@staticmethod |
|
||||
def save_sms(sms): |
|
||||
print('Inbox %s:' % sms.who, sms.text) |
|
||||
if not isinstance(sms, SMS): |
|
||||
raise TypeError |
|
||||
response = secure_request({ |
|
||||
'who': sms.who, |
|
||||
'dev': sms.dev, |
|
||||
'text': sms.text, |
|
||||
'cmd': 'save_sms' |
|
||||
}) |
|
||||
if response is not None: |
|
||||
print(response) |
|
||||
|
|
||||
def send_sms(self, dev, recipient, utext): |
|
||||
if not validate_tel(recipient): |
|
||||
print("Tel %s is not valid" % recipient) |
|
||||
return |
|
||||
sms = SmsSubmit(recipient, utext) |
|
||||
for pdu in sms.to_pdu(): |
|
||||
response = self.command('dongle pdu %s %s' % (dev, pdu.pdu)) |
|
||||
print(response.data) |
|
||||
|
|
||||
def push_text(self, sms, ref, cnt): |
|
||||
if not isinstance(sms, SMS): |
|
||||
raise TypeError |
|
||||
chunk = [c for c in self.sms_chunks if c.ref == ref] |
|
||||
chunk_len = len(chunk) |
|
||||
if chunk_len == 1: |
|
||||
chunk = chunk[0] |
|
||||
chunk.sms += sms |
|
||||
if chunk.sms_count == cnt: |
|
||||
self.save_sms(chunk.sms) |
|
||||
self.sms_chunks.remove(chunk) |
|
||||
|
|
||||
elif chunk_len == 0: |
|
||||
self.new_chunked_sms(cnt, ref, sms) |
|
||||
|
|
||||
def send_from_outbox(self): |
|
||||
messages = secure_request({'cmd': 'get_new'}) |
|
||||
for msg in messages: |
|
||||
if self.send_sms(dev='sim_8318999', recipient=msg.dst, utext=msg.text): |
|
||||
msg_status = 'st' |
|
||||
else: |
|
||||
msg_status = 'fd' |
|
||||
result = secure_request({ |
|
||||
'cmd': 'update_status', |
|
||||
'mid': msg.pk, |
|
||||
'status': msg_status |
|
||||
}) |
|
||||
if result is not None: |
|
||||
print(result) |
|
||||
|
|
||||
|
|
||||
manager = MyAstManager() |
|
||||
|
|
||||
|
|
||||
def validate_tel(tel, reg=re.compile(r'^\+7978\d{7}$')): |
|
||||
return bool(re.match(reg, tel)) |
|
||||
|
|
||||
|
|
||||
def handle_shutdown(event, mngr): |
|
||||
print("Received shutdown event") |
|
||||
mngr.close() |
|
||||
# we could analyze the event and reconnect here |
|
||||
|
|
||||
|
|
||||
def signal_handler(signum, frame): |
|
||||
if signum != 10: |
|
||||
return |
|
||||
global outbox_messages |
|
||||
outbox_messages = True |
|
||||
|
|
||||
|
|
||||
def handle_inbox_long_sms_message(event, mngr): |
|
||||
if event.has_header('Message'): |
|
||||
pdu = event.get_header('Message') |
|
||||
pdu = re.sub(r'^\+CMGR:\s\d,,\d{1,3}\\r\\n', '', pdu) |
|
||||
sd = SmsDeliver(pdu) |
|
||||
data = sd.data |
|
||||
chunks_count = data.get('cnt') |
|
||||
sms = SMS( |
|
||||
text=data.get('text'), |
|
||||
who=data.get('number'), |
|
||||
dev=event.get_header('Device') |
|
||||
) |
|
||||
if chunks_count is not None: |
|
||||
# more than 1 message |
|
||||
mngr.push_text(sms=sms, ref=data.get('ref'), cnt=chunks_count) |
|
||||
else: |
|
||||
# one message |
|
||||
mngr.save_sms(sms) |
|
||||
|
|
||||
|
|
||||
@pidfile(pidname='dialing.py.pid', piddir='/run') |
|
||||
def main(): |
|
||||
global outbox_messages |
|
||||
try: |
|
||||
manager.connect(ASTERISK_MANAGER_AUTH['host']) |
|
||||
manager.login(ASTERISK_MANAGER_AUTH['username'], ASTERISK_MANAGER_AUTH['password']) |
|
||||
|
|
||||
# register some callbacks |
|
||||
manager.register_event('Shutdown', handle_shutdown) |
|
||||
manager.register_event('DongleNewCMGR', handle_inbox_long_sms_message) # PDU Here |
|
||||
|
|
||||
# get a status report |
|
||||
response = manager.status() |
|
||||
print(response) |
|
||||
|
|
||||
signal.signal(signal.SIGUSR1, handler=signal_handler) |
|
||||
|
|
||||
while True: |
|
||||
if outbox_messages: |
|
||||
outbox_messages = False |
|
||||
manager.send_from_outbox() |
|
||||
sleep(5) |
|
||||
|
|
||||
except ast_mngr.ManagerSocketException as e: |
|
||||
print("Error connecting to the manager: ", e) |
|
||||
except ast_mngr.ManagerAuthException as e: |
|
||||
print("Error logging in to the manager: ", e) |
|
||||
except ast_mngr.ManagerException as e: |
|
||||
print("Error: ", e) |
|
||||
finally: |
|
||||
manager.logoff() |
|
||||
|
|
||||
|
|
||||
if __name__ == '__main__': |
|
||||
main() |
|
||||
@ -0,0 +1,310 @@ |
|||||
|
## Установка: |
||||
|
Работа предполагается на python3. |
||||
|
Я предпочитаю запускать wsgi сервер на связке uWSGI + Nginx, так что ставить будем соответствующие пакеты. |
||||
|
|
||||
|
##### Подготовка системы |
||||
|
Установка происходит в debian версии 9.5. |
||||
|
|
||||
|
Для начала подготовим систему, очистим и обновим пакеты. Процесс обновления долгий, так что можно пойти заварить себе чай :) |
||||
|
``` |
||||
|
# dnf clean all |
||||
|
# dnf -y update |
||||
|
``` |
||||
|
|
||||
|
Затем установим зависимости, в Fedora 25 пакеты называются так: |
||||
|
``` |
||||
|
# dnf -y install python3 python3-devel python3-pip python3-pillow mariadb mariadb-devel uwsgi nginx uwsgi-plugin-python3 net-snmp net-snmp-libs net-snmp-utils net-snmp-devel net-snmp-python git redhat-rpm-config curl-devel expect |
||||
|
``` |
||||
|
|
||||
|
Для Debian 9 это выглядит так: |
||||
|
``` |
||||
|
# apt install mariadb-server libmariadb-dev mariadb-client python3-dev python3-pip python3-pil uwsgi nginx uwsgi-plugin-python3 libsnmp-dev git gettext libcurl4-openssl-dev libssl-dev expect |
||||
|
``` |
||||
|
|
||||
|
Условимся что путь к папке с проектом находится по адресу: */var/www/djing*. |
||||
|
Дальше создадим каталок для web, затем создаём virtualenv, обновляем pip и ставим проект через pip: |
||||
|
```bash |
||||
|
# mkdir /var/www |
||||
|
# cd /var/www |
||||
|
# git clone --depth=1 https://github.com/nerosketch/djing.git |
||||
|
# python3 -m venv venv |
||||
|
# cd djing |
||||
|
# source ./venv/bin/activate |
||||
|
# pip3 install --upgrade pip |
||||
|
# export PYCURL_SSL_LIBRARY=openssl |
||||
|
# pip3 install -r djing/requirements.txt |
||||
|
# chown -R www-data:www-data /var/www/djing |
||||
|
# deactivate |
||||
|
``` |
||||
|
|
||||
|
Или, вместо этих комманд выполните инстальник из *install/install_debian.sh* если у вас *debian*, |
||||
|
или по аналогии для других дистрибутивов. |
||||
|
|
||||
|
Теперь давайте перейдём в баш от имени пользователя www-data, так у нас будет хватать прав на все |
||||
|
директории и файлы |
||||
|
```bash |
||||
|
sudo -u www-data -g www-data bash && cd / |
||||
|
``` |
||||
|
|
||||
|
Скопируем конфиг из примера в реальный: |
||||
|
```bash |
||||
|
$ cd /var/www/djing |
||||
|
$ cp djing/local_settings.py.example djing/settings.py |
||||
|
``` |
||||
|
|
||||
|
Затем отредактируйте конфиг для своих нужд. |
||||
|
|
||||
|
В Debian использую пользователя www-data, остаётся только назначить владельца на папки: |
||||
|
```bash |
||||
|
# chown -R www-data:www-data /var/www/djing |
||||
|
``` |
||||
|
|
||||
|
|
||||
|
### Настройка WEB Сервера |
||||
|
Конфиг Nginx в папке *sites-available* на моём рабочем сервере выглядит примерно так как указано |
||||
|
ниже, не забудьте указать в нужных местах ваш домен. |
||||
|
```nginx |
||||
|
upstream djing{ |
||||
|
server unix:///run/uwsgi/app/djing/socket; |
||||
|
} |
||||
|
|
||||
|
# Для обращений в web серверу на localhost из скриптов |
||||
|
server { |
||||
|
listen 80; |
||||
|
server_name localhost 127.0.0.1; |
||||
|
location / { |
||||
|
uwsgi_pass djing; |
||||
|
include uwsgi_params; |
||||
|
} |
||||
|
access_log /dev/null; |
||||
|
error_log /dev/null; |
||||
|
} |
||||
|
|
||||
|
# Это редирект с http на https, если у вас есть ssl сертификат |
||||
|
server{ |
||||
|
listen 80; |
||||
|
server_name your-domain.com; |
||||
|
return 301 https://your-domain.com$request_uri; |
||||
|
} |
||||
|
|
||||
|
# обработка http запросов. |
||||
|
server { |
||||
|
listen 80 default_server; |
||||
|
server_name <ваш домен>; |
||||
|
root /var/www/djing/; |
||||
|
charset utf-8; |
||||
|
|
||||
|
location = /favicon.ico { alias /var/www/djing/static/img/favicon_m.ico; } |
||||
|
location = /robots.txt { alias /var/www/djing/robots.txt; } |
||||
|
|
||||
|
location /media { |
||||
|
alias /var/www/djing/media; |
||||
|
expires 7d; |
||||
|
} |
||||
|
|
||||
|
location /static { |
||||
|
alias /var/www/djing/static; |
||||
|
expires 1d; |
||||
|
} |
||||
|
|
||||
|
location / { |
||||
|
uwsgi_pass djing; |
||||
|
include uwsgi_params; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
# Обработка https запросов |
||||
|
server { |
||||
|
listen 443 ssl; |
||||
|
ssl on; |
||||
|
server_name <ваш домен> www.<ваш домен>; |
||||
|
|
||||
|
ssl_certificate "/путь/к/вашему/сертификату.crt"; |
||||
|
ssl_certificate_key "/путь/к/вашему/сертификату.key"; |
||||
|
ssl_session_cache shared:SSL:1m; |
||||
|
ssl_session_timeout 5m; |
||||
|
ssl_ciphers HIGH:!aNULL:!MD5; |
||||
|
ssl_prefer_server_ciphers on; |
||||
|
|
||||
|
location = /favicon.ico { alias /var/www/djing/static/img/favicon_m.ico; } |
||||
|
location = /robots.txt { alias /var/www/djing/robots.txt; } |
||||
|
|
||||
|
location /media { |
||||
|
alias /var/www/djing/media; |
||||
|
expires 7d; |
||||
|
} |
||||
|
|
||||
|
location /static { |
||||
|
alias /var/www/djing/static; |
||||
|
expires 1d; |
||||
|
} |
||||
|
|
||||
|
location / { |
||||
|
uwsgi_pass djing; |
||||
|
include uwsgi_params; |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
Это минимальный конфиг Nginx для работы. Проверте файл /run/uwsgi/djing.sock на доступность пользователю www-data для чтения. |
||||
|
|
||||
|
Далее настраиваем uWSGI. Мой конфиг для uWSGI в debian: |
||||
|
> /etc/uwsgi/apps-available/djing.ini |
||||
|
```ini |
||||
|
[uwsgi] |
||||
|
chdir=/var/www/djing |
||||
|
module=djing.wsgi |
||||
|
master=True |
||||
|
processes=8 |
||||
|
socket=/run/uwsgi/app/djing/socket |
||||
|
;http-socket=:8000 |
||||
|
chmod-socket=644 |
||||
|
;pidfile=/run/uwsgi/django-master.pid |
||||
|
vacuum=True |
||||
|
plugin=python3 |
||||
|
;disable-logging=True |
||||
|
venv=/var/www/djing/venv |
||||
|
``` |
||||
|
|
||||
|
А теперь попробуем запустить биллинг в полной связке Python - Uwsgi - Nginx. |
||||
|
Перейдём в папку биллинга, если вы вышли куда-то ещё, зайдём в баш из под пользователя www-data. |
||||
|
```bash |
||||
|
sudo -u www-data -g www-data bash |
||||
|
cd /var/www/djing |
||||
|
source ./venv/bin/activate |
||||
|
``` |
||||
|
|
||||
|
И скомпилируем переводы: |
||||
|
> \$ ./manage.py compilemessages -l ru |
||||
|
|
||||
|
|
||||
|
Попробуем запустить *uwsgi* и *djing* без *Nginx*, на порт 8000: |
||||
|
Раскомментируйте строку *http-socket=:8000* в файле *djing.ini*, и закомментируйте |
||||
|
*socket=/run/uwsgi/app/djing/socket* и *chmod-socket=644*, теперь можно попробовать запустить |
||||
|
> \# uwsgi --gid www-data --uid www-data /etc/uwsgi/apps-available/djing.ini |
||||
|
|
||||
|
пробуем зайти в биллинг с браузера на <адрес сервера>:8000. Вам должен показаться диалог входа в систему: |
||||
|
 |
||||
|
|
||||
|
Теперь, если всё прошло успешно, поменяйте в конфиге */etc/uwsgi.d/djing.ini* сокет с http-socket на unix socket: |
||||
|
Раскомментируйте это: |
||||
|
> socket=/run/uwsgi/app/djing/socket |
||||
|
|
||||
|
И закомментируйте эту строку: |
||||
|
> http-socket=:8000 |
||||
|
|
||||
|
Строка *http-socket=:8000* была для теста, чтоб посмотреть работает-ли uwsgi сам по себе. |
||||
|
|
||||
|
Теперь можно попробовать запустить *nginx* и *uwsgi*. Ставим в **djing/settings.py** опцию **DEBUG = False**, |
||||
|
и пробуем запустить нужные юниты: |
||||
|
|
||||
|
> \# systemctl start uwsgi\ |
||||
|
> \# systemctl start nginx |
||||
|
|
||||
|
|
||||
|
### Настраиваем биллинг |
||||
|
Все настройки биллинга находятся в файле *djing/settings.py*. Большинство опций вы можете найти в документации |
||||
|
[Django settings](https://docs.djangoproject.com/en/2.1/ref/settings). |
||||
|
Те опции, которые были добавлены мной в рамках проекта *djing*, описаны ниже в этом разделе документации по установке. |
||||
|
|
||||
|
#### djing/settings.py |
||||
|
**USE_TZ** — Это опция *Django*, но если вы не работаете в разных часовых диапазонах то я не рекомендую включать |
||||
|
эту опцию чтоб небыло путаницы со временем. Это связано с тем что я ещё не тестировал поведение работы со временем при |
||||
|
включённой опции *USE_TZ*. |
||||
|
|
||||
|
**ALLOWED_HOSTS** — Тоже опция *Django*, но важная для безопасности, укажите в списке возможные имена вашего сервера. |
||||
|
Подробнее в документации [Django settings](https://docs.djangoproject.com/en/2.1/ref/settings/#allowed-hosts). |
||||
|
|
||||
|
**DEFAULT_PICTURE** — Это путь к изображению по умолчанию, оно используется когда нужное изображение не найдено. |
||||
|
|
||||
|
**PAGINATION_ITEMS_PER_PAGE** — Количество выводимых элементов списка на странце с таблицей. Например, если поставить 30, |
||||
|
то на странице абонентов на одной странице будет выведено 30 строк абонентов. |
||||
|
|
||||
|
**DEFAULT_SNMP_PASSWORD** — Пароль snmp по умолчанию для устройств, чтоб при создании устройства он был заполнен в нужном поле. |
||||
|
Если нет такого пароля то оставьте пустым или None. |
||||
|
|
||||
|
**TELEPHONE_REGEXP** — Регулярное выражение для валидации номера телефона. |
||||
|
|
||||
|
**API_AUTH_SECRET** — Секретное слово для безопасной передачи комманд от скриптов. |
||||
|
Содержимое данных можно увидеть, но нельзя изменить. Это нельзя применять для передачи паролей, |
||||
|
секретных номеров, но вполне подходит для защищённого управления. Безопасность гарантируется хеш суммой |
||||
|
__sha256__. Секретное слово должен знать биллинг в конфиге, и доверенный скрипт на примере *agent/monitoring_agent.py* |
||||
|
Позаботьтесь о том чтоб скрипт нельзя было просто так прочитать, или вынесите секретное слово куда-то. Если кто-то лишний узнает |
||||
|
его то ваша система будет под угрозой. |
||||
|
|
||||
|
**API_AUTH_SUBNET** — Так же применяется для авторизации скриптов, но проверяет подсеть с которой была отправлена |
||||
|
комманда. Даже если скрипт будет знать секретное слово, но не будет находится в одной из доверенных |
||||
|
подсетей то в доступе будет отказано. Может быть строковым представлением подсети, например '127.0.0.1/8', или списком |
||||
|
подсетей в строковом представлении. Можно даже передать объект который на выходе при преобразовании в строку |
||||
|
даст подсеть. |
||||
|
|
||||
|
**COMPANY_NAME** — Название вашей компании, будет отображаться в шапке сайта в административной части |
||||
|
и в личном кабинете абонента. |
||||
|
|
||||
|
**TELEGRAM_BOT_TOKEN** — Когда вы включите оповещение через телеграм то вам сюда. |
||||
|
|
||||
|
|
||||
|
#### Создание БД |
||||
|
Подразумевается что сервер баз данных у вас уже есть, или вы его можете установить сами. |
||||
|
В конфиге настроить БД можно по инструкции [Django databases](https://docs.djangoproject.com/en/2.1/ref/settings/#databases). |
||||
|
|
||||
|
Убедитесть что вы в папке с проектом, комманда **pwd** должна выдать */var/www/djing*. |
||||
|
Чтоб создать бд, как описано в документации [Django admin \& migrate](https://docs.djangoproject.com/en/2.1/ref/django-admin/#migrate), |
||||
|
нужно запустить **./manage.py migrate** чтоб создать структуру БД. Вывод будет примерно таким: |
||||
|
``` |
||||
|
$ ./manage.py migrate |
||||
|
Operations to perform: |
||||
|
Apply all migrations: mapapp, contenttypes, msg_app, taskapp, accounts_app, devapp, statistics, tariff_app, admin, sessions, chatbot, auth, abonapp |
||||
|
Running migrations: |
||||
|
Rendering model states... DONE |
||||
|
Applying mapapp.0001_initial... OK |
||||
|
Applying devapp.0001_initial... OK |
||||
|
Applying devapp.0002_auto_20160909_1018... OK |
||||
|
Applying devapp.0003_device_map_dot... OK |
||||
|
Applying contenttypes.0001_initial... OK |
||||
|
... |
||||
|
Applying taskapp.0012_auto_20170407_0124... OK |
||||
|
Applying taskapp.0013_auto_20170413_1944... OK |
||||
|
Applying taskapp.0014_auto_20170416_1029... OK |
||||
|
Applying taskapp.0015_auto_20170816_1109... OK |
||||
|
``` |
||||
|
|
||||
|
После этого вам стоит создать супер пользователя чтоб зайти в систему. |
||||
|
``` |
||||
|
$ ./manage.py createsuperuser |
||||
|
``` |
||||
|
В интерактивном режиме ответьте на вопросы. |
||||
|
``` |
||||
|
$ ./manage.py createsuperuser |
||||
|
Username: username |
||||
|
Telephone: +12223334455 |
||||
|
Password: |
||||
|
Password (again): |
||||
|
Superuser created successfully. |
||||
|
``` |
||||
|
Обратите внимание на то что номер телефона это обязательное поле для заполнения. |
||||
|
Если у вас не выходит указать номер телефона, то проверте чтоб ваш телефон соответствовал регулярному выражению **^(\+[7,8,9,3]\d{10,11})?$**. |
||||
|
Если регулярное выражение вам не подхожит, то вы можете изенить его в настройках, см. опции в настройках выше. |
||||
|
После изменения настроек они не сразу вступят в силу, нужно перезагрузить код django, для этого перезапустите **uwsgi**: |
||||
|
> \# systemctl restart uwsgi |
||||
|
|
||||
|
Теперь произведите тестовый запуск: |
||||
|
> \$ ./manage.py runserver 192.168.0.100:8000 |
||||
|
|
||||
|
Если не подтягивается статика то проверте чтоб опция **DEBUG** в настройках была **True**. |
||||
|
|
||||
|
При условии что адрес вашего сервера *192.168.0.100*, вы сможете открыть биллинг по адресу **http://192.168.0.100:8000/**. |
||||
|
Введите логин и пароль супер пользователя которого вы создали по инструкции выше. |
||||
|
|
||||
|
Если вы успешно зашли то можно пробовать запускать биллинг в рабочую обстановку. |
||||
|
В настройках смените переменную **DEBUG** на **False** и перезапустите *uwsgi*. |
||||
|
|
||||
|
### Настраиваем демоны |
||||
|
Если ваша система работает с поддержкой [**systemd**](https://www.freedesktop.org/wiki/Software/systemd/) то в каталоге *systemd_units* проекта вы найдёте юниты для systemd. |
||||
|
Скопируйте их в каталог юнитов systemd, у меня это путь */etc/systemd/system*. |
||||
|
__Настоятельно рекомендую заглянуть внутрь этих юнитов__. Проверте пути исполняемых файлов, права и прочее. |
||||
|
|
||||
|
Для запуска сервиса **djing_rotate.service** вам нужно сначала настроить сбор статистики по [netflow](./netflow.md). |
||||
|
|
||||
|
Перед включением юнита *djing_telebot.service* создайте Telegram бота и впишите в файл *djing/settings.py* в переменную *TELEGRAM_BOT_TOKEN* токен вашего бота. |
||||
|
С помощью этого бота вы будете получать различные сообщения из биллинга. Подробнее в инструкции к [модулю оповещений](./bot.md). |
||||
@ -0,0 +1,13 @@ |
|||||
|
[uwsgi] |
||||
|
chdir=/var/www/djing |
||||
|
module=djing.wsgi |
||||
|
master=True |
||||
|
processes=8 |
||||
|
socket=/run/uwsgi/app/djing/socket |
||||
|
;http-socket=:8000 |
||||
|
chmod-socket=644 |
||||
|
;pidfile=/run/uwsgi/django-master.pid |
||||
|
vacuum=True |
||||
|
plugin=python3 |
||||
|
;disable-logging=True |
||||
|
venv=/var/www/djing/venv |
||||
@ -0,0 +1,42 @@ |
|||||
|
upstream djing{ |
||||
|
server unix:///run/uwsgi/app/djing/socket; |
||||
|
} |
||||
|
|
||||
|
# Для обращений в web серверу на localhost из скриптов |
||||
|
server { |
||||
|
listen 80; |
||||
|
server_name localhost 127.0.0.1; |
||||
|
location / { |
||||
|
uwsgi_pass djing; |
||||
|
include uwsgi_params; |
||||
|
} |
||||
|
access_log /dev/null; |
||||
|
error_log /dev/null; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
# обработка http запросов. |
||||
|
server { |
||||
|
listen 80 default_server; |
||||
|
server_name _; |
||||
|
root /var/www/djing/; |
||||
|
charset utf-8; |
||||
|
|
||||
|
location = /favicon.ico { alias /var/www/djing/static/img/favicon_m.ico; } |
||||
|
location = /robots.txt { alias /var/www/djing/robots.txt; } |
||||
|
|
||||
|
location /media { |
||||
|
alias /var/www/djing/media; |
||||
|
expires 7d; |
||||
|
} |
||||
|
|
||||
|
location /static { |
||||
|
alias /var/www/djing/static; |
||||
|
expires 1d; |
||||
|
} |
||||
|
|
||||
|
location / { |
||||
|
uwsgi_pass djing; |
||||
|
include uwsgi_params; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,4 @@ |
|||||
|
User-agent: * |
||||
|
Allow: /$ |
||||
|
Allow: /accounts/login/ |
||||
|
Disallow: / |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue