Как создать свой веб сервер
Перейти к содержимому

Как создать свой веб сервер

  • автор:

Как создать свой первый безопасный веб-сервер, готовый к продуктиву

В этом руководстве мы рассмотрим некоторые из лучших методик создания своего первого безопасного сервера. Мы пошагово разберём весь процесс, и в результате получим сервер, полностью готовый к использованию в продуктиве для вашего приложения. Конечно, это не исчерпывающее руководство. Безопасный сервер — это постоянный поиск новых ресурсов и бесконечные улучшения. Но с этим материалом вы можете начать создавать собственную инфраструктуру.

Для прогона тестов мы будем использовать Amazon EC2, но можно взять и Amazon LightSail, Digital Ocean, Vultr или другой сервис. Все они конфигурируются одинаково, так что выбирайте тот, который вам по душе.

Создаём публичный и приватный SSH-ключи

Сначала создадим пару ключей, которые понадобятся некоторым хостам при установке сервера. Этот и некоторые другие шаги можно пропустить, если вы решите создать свою пару ключей при запуске сервера на Amazon.

SSH-ключи мы будем создавать с помощью ssh-keygen.

$ ssh-keygen -t rsa -b 4096

В результате получим два файла: id_rsa и id_rsa.pub (приватный и публичный ключи). Никогда и никому не передавайте свой приватный ключ.

Подробную инструкцию по созданию ключей вы найдёте здесь.

Импорт публичного ключа в Amazon

Импортируем только что созданный публичный ключ в платформу Amazon.

  1. Заходим в консоль управления Amazon.
  2. Кликаем AWS services → Compute > EC2
  3. Кликаем на левое меню Network & Security → Key Pairs
  4. Кликаем «Import Key Pair» и загружаем публичный ключ (id_rsa.pub)

Создаём свою виртуальную машину

Установим в Amazon EC2 виртуальную машину под управлением Ubuntu. Настройка подробно описана здесь:

  1. Заходим в консоль управления Amazon.
  2. Кликаем AWS services → Compute → EC2
  3. Выбираем запускаемый экземпляр.
  4. Выбираем один из образов. В нашем случае это будет Ubuntu Server 16.04 LTS (HVM), с SSD-накопителем (но вы можете выбрать то, что вам больше подходит).
  5. Выбираем виртуальную машину (в соответствии с вашими нуждами). Кликаем «Review» и «Launch».
  6. Открываем новую вкладку и импортируем в Amazon созданный публичный ключ.
  7. Здесь нас попросят «выбрать существующую пару ключей или создать новую» («Select an existing key pair or create a new key pair»). Жмём «выбрать существующую» («Choose an existing key pair»). Выбираем ранее загруженный ключ.
  8. Кликаем «Launch Instances».
  9. Кликаем на ссылку виртуальной машины, которую мы только что создали.

Подключаемся к новому серверу

Обращаемся к виртуальной машине по SSH.

Пишем в терминале:

$ ssh @ -p 22 -i
  • : пользователь Linux-системы. В случае с Amazon используйте ubuntu, на других сервисах — root
  • : IP-адрес созданной нами виртуальной машины. Это поле «Public DNS (IPv4)» во вкладке «Description» нашего сервера.
  • : полный путь к сгенерированному ранее приватному ключу (например, /Users/flavio/.ssh/id_rsa).
  • -i : это можно пропустить, если вы добавили ключ в свой SSH-агент.

Даём доступ новому пользователю

Создадим новый аккаунт пользователя по имени “wizard”:

$ sudo adduser wizard

Дадим “wizard” разрешение выполнять sudo. Откроем файл:

$ sudo nano /etc/sudoers.d/wizard

И зададим содержимое:

wizard ALL=(ALL) NOPASSWD:ALL
$ mkdir /home/wizard/.ssh # create authorized_keys file and copy your public key here $ nano /home/wizard/.ssh/authorized_keys $ chown wizard /home/wizard/.ssh $ chown wizard /home/wizard/.ssh/authorized_keys

Скопируем публичный ключ (PATH-TO-PUBLIC-KEY) и вставим в удалённый экземпляр /home/wizard/.ssh/authorized_keys. Настроим разрешения:

$ chmod 700 /home/wizard/.ssh $ chmod 600 /home/wizard/.ssh/authorized_keys

Обеспечиваем безопасность

Обновляем все установленные пакеты.

$ sudo apt-get update $ sudo apt-get upgrade

Меняем SSH-порт с 22 на 2201. Для конфигурирования файрвола (ufw, Uncomplicated Firewall, незатейливый файрвол) открываем файл /etc/ssh/sshd_config:

$ sudo nano /etc/ssh/sshd_config

и меняем эти данные:

Port 2201 PermitRootLogin no PasswordAuthentication no # add this to avoid problem with multiple sshd processes ClientAliveInterval 600 ClientAliveCountMax 3
$ sudo service ssh restart

Конфигурируем Uncomplicated Firewall (UFW) так, чтобы пропускались только входящие подключения SSH (порт 2201), HTTP (порт 80) и NTP (порт 123).

# close all incoming ports $ sudo ufw default deny incoming # open all outgoing ports $ sudo ufw default allow outgoing # open ssh port $ sudo ufw allow 2201/tcp # open http port $ sudo ufw allow 80/tcp # open ntp port : to sync the clock of your machine $ sudo ufw allow 123/udp # turn on firewall $ sudo ufw enable

Конфигурируем серверные часы

Устанавливаем в качестве локального часового пояса UTC:

$ sudo dpkg-reconfigure tzdata

Выбираем опцию ‘None of the Above’ и снова UTC.

Отключаемся и добавляем наш ключ в SSH-агент

Для отключения вводим:

$ exit

а потом добавляем ключ.

Добавляем в Amazon разрешения по порту

Это необходимо сделать в Amazon. Зададим SSH-порт, который будем использовать также на Amazon.

  1. Заходим в консоль управления Amazon.
  2. Кликаем AWS services > Compute > EC2
  3. Кликаем на левое меню Network & Security → Security Groups
  4. Выбираем группу безопасности, относящуюся к нашей виртуальной машине.
  5. Кликаем Action > Edit Inbound Rules
  6. Кликаем «добавить правило» («Add Rule») и задаём: Type: Custom TCP, Port Range: 2201, Source: 0.0.0.0/0 и Description: SSH

Подключаемся с новыми данными

Теперь вы можете подключиться к серверу по новому порту как новый пользователь:

$ ssh wizard@ -p 2201 -i

Пишем свой веб-сервер на Python: сокеты

Подпишись на обновления блогa, чтобы не пропустить следующий пост!

Оглавление
  • Что определяет хорошего разработчика ПО?
  • Что же такое веб-сервер?
  • Как общаться с клиентами по сети
  • Простейший TCP сервер
  • Простейший TCP клиент
  • Заключение
  • Cсылки по теме
Лирическое отступление: что определяет хорошего разработчика?

Доктор Манхэттен что-то собирает силой мысли

Разработка ПО — это инженерная дисциплина. Если вы хотите стать действительно профессиональным разработчиком, то необходимо в себе развивать качества инженера, а именно: системный подход к решению задач и аналитический склад ума. Для вас должно перестать существовать слово магия. Вы должны точно знать как и почему работают системы, с которыми вы взаимодействуете (между прочим, полезное качество, которое находит применение и за пределами IT).

К сожалениею (или к счастью, ибо благоприятно складывается на уровне доходов тех, кто осознал), существует огромное множество людей, которые пишут код без должного понимания важности этих принципов. Да, такие горе-программисты могут создавать работающие до поры до времени системы, собирая их из найденных в Интернете кусочков кода, даже не удосужившись прочитать, как они реализованы. Но как только возникает первая нестандартная проблема, решение которой не удается найти на StackOverflow, вышеупомянутые персонажи превращаются в беспомощных жертв кажущейся простоты современной разработки ПО.

Для того, чтобы не оказаться одним из таких бедолаг, необходимо постоянно инвестировать свое время в получение фундаментальных знаний из области Computer Science. В частности, для прикладных разработчиков в большинстве случаев таким фундаментом является операционная система, в которой выполняются созданные ими программы.

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

Что такое веб-сервер?

Начнем с того, что четко ответим на вопрос, что же такое веб-сервер?

В первую очередь — это сервер. А сервер — это процесс (да, это не железка), обслуживающий клиентов. Сервер — фактически обычная программа, запущенная в операционной системе. Веб-сервер, как и большинство программ, получает данные на вход, преобразовывает их в соответствии с бизнес-требованиями и осуществляет вывод данных. Данные на вход и выход передаются по сети с использованием протокола HTTP. Входные данные — это запросы клиентов (в основном веб-браузеров и мобильных приложений). Выходные данные — это зачастую HTML-код подготовленных веб-страниц.

Клиент общается с сервером по сети

На данном этапе логичными будут следующие вопросы: что такое HTTP и как передавать данные по сети? HTTP — это простой текстовый (т.е. данные могут быть прочитаны человеком) протокол передачи информации в сети Интернет. Протокол — это не страшное слово, а всего лишь набор соглашений между двумя и более сторонами о правилах и формате передачи данных. Его рассмотрение мы вынесем в отдельную тему, а далее попробуем понять, как можно осуществлять передачу данных по сети.

Как компьютеры взаимодействуют по сети

В Unix-подобных системах принят очень удобный подход для работы с различными устройствами ввода/вывода — рассматривать их как файлы. Реальные файлы на диске, мышки, принтеры, модемы и т.п. являются файлами. Т.е. их можно открыть, прочитать данные, записать данные и закрыть.

ls /dev показывает список устройств Linux

При открытии файла операционной системой создается т.н. файловый дескриптор. Это некоторый целочисленный идентификатор, однозначно определяющий файл в текущем процессе. Для того, чтобы прочитать или записать данные в файл, необходимо в соответсвующую функцию (например, read() или write() ) передать этот дескриптор, чтобы четко указать, с каким файлом мы собираемся взаимодействовать.

int fd = open("/path/to/my/file", . ); char buffer[1024]; read(fd, buffer, 1024); write(fd, "some data", 10); close(fd); 

Очевидно, что т.к. общение компьютеров по сети — это также про ввод/вывод, то и оно должно быть организовано как работа с файлами. Для этого используется специальный тип файлов, т.н. сокеты.

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

Berkeley Sockets напоминают собой всем известную электрическую розетку

Т.к. видов межпроцессных взаимодействий с помощью сокетов множество, то и сокеты могут иметь различные конфигурации: сокет характеризуется семейством протоколов (IPv4 или IPv6 для сетевого и UNIX для локального взаимодействия), типом передачи данных (потоковая или датаграммная) и протоколом (TCP, UDP и т.п.).

Далее будет рассматриваться исключительно клиент-серверное взаимодействие по сети с использованием сокетов и стека протоколов TCP/IP.

Предположим, что наша прикладная программа хочет передать строку «Hello World» по сети, и соответствующий сокет уже открыт. Программа осуществляет запись этой строки в сокет с использованием функции write() или send() . Как эти данные будут переданы по сети?

Т.к. в общем случае размер передаваемых программой данных не ограничен, а за один раз сетевой адаптер (NIC) может передать фиксировнный объем информации, данные необходимо разбить на фрагменты, не превышающие этот объем. Такие фрагменты называются пакетами. Каждому пакету добавляется некоторая служебная информация, в частности содержащая адреса получателя и отправителя, и они начинают свой путь по сети.

Компьютер отправляет данные по сети разделив на фрагменты

Адрес компьютера в сети — это т.н. IP-адрес. IP (Internet Protocol) — протокол, который позволил объединить множество разнородных сетей по всеми миру в одну общую сеть, которая называется Интернет. И произошло это благодаря тому, что каждому компьютеру в сети был назначен собственный адрес.

В силу особенности маршрутизации пакетов в сети, различные пакеты одной и той же логической порции данных могут следовать от отправителя к получателю разными маршрутами. Разные маршруты могут иметь различную сетевую задержку, следовательно, пакеты могут быть доставлены получателю не в том порядке, в котором они были отправлены. Более того, содержимое пакетов может быть повреждено в процессе передачи.

TCP reassembly - восстанавливаем порядок пакетов на принимающей стороне

Вообще говоря, требование получать пакеты в том же порядке, в котором они были отправлены, не всегда является обязательным (например, при передаче потокового видео). Но, когда мы загружаем веб-страницу в браузере, мы ожидаем, что буквы на ней будут расположены ровно в том же порядке, в котором их нам отправил веб-сервер. Именно поэтому HTTP протокол работает поверх надеждного протокола передачи данных TCP, который будет рассмотрен ниже.

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

Этим занимается специальный протокол потоковой передачи данных — TCP.

TCP — (Transmission Control Protocol — протокол управления передачей) — один из основных протоколов передачи данных в Интернете. Используется для надежной передачи данных с подтверждением доставки и сохранением порядка пакетов.

TCP segment внутри IP пакета

В силу того, что передачей данных по сети по протоколу TCP на одном и том же компьютере может заниматься одновременно несколько программ, для каждого из таких сеансов передачи данных необходимо поддерживать свою последовательность пакетов. Для этого TCP вводит понятие соединения. Соединение — это просто логическое соглашение между принимающей и передающей сторонами о начальных и текущих значениях номеров пакетов и состоянии передачи. Соединение необходимо установить (обменявшись несколькими служебными пакетами), поддерживать (периодически передавать данные, чтобы не наступил таймаут), а затем закрыть (снова обменявшись несколькими служебными пакетами).

Итак, IP определяет адрес компьютера в сети. Но, в силу наличия TCP соединений, пакеты могут принадлежать различным соединениям на одной и той же машине. Для того, чтобы различать соединения, вводится понятие TCP-порт. Это всего лишь пара чисел (одно для отправителя, а другое для получателя) в служебной информации пакета, определяющая, в рамках какого соединения должен рассматриваться пакет. Т.е. адрес соединения на этой машине.

Простейший TCP сервер

Теперь перейдем к практике. Попробуем создать свой собственный TCP-сервер. Для этого нам понадобится модуль socket из стандартной библиотеки Python.

Основная проблема при работе с сокетами у новичков связана с наличием обязательного магического ритуала подготовки сокетов к работе. Но имея за плечами теоретические знания, изложенные выше, кажущаяся магия превращается в осмысленные действия. Также необходимо отметить, что в случае с TCP работа с сокетами на сервере и на клиенте различается. Сервер занимается ожиданием подключений клиентов. Т.е. его IP адрес и TCP порт известны потенциальным клиентам заранее. Клиент может подключиться к серверу, т.е. выступает активной стороной. Сервер же ничего не знает об адресе клиента до момента подключения и не может выступать инициатором соединения. После того, как сервер принимает входящее соединения клиента, на стороне сервера создается еще один сокет, который является симметричным сокету клиента.

Итак, создаем серверный сокет:

# python3 import socket serv_sock = socket.socket(socket.AF_INET, # задамем семейство протоколов 'Интернет' (INET) socket.SOCK_STREAM, # задаем тип передачи данных 'потоковый' (TCP) proto=0) # выбираем протокол 'по умолчанию' для TCP, т.е. IP print(type(serv_sock)) #

А где же обещанные int fd = open(«/path/to/my/socket») ? Дело в том, что системный вызов open() не позволяет передать все необходимые для инициализации сокета параметры, поэтому для сокетов был введен специальный одноименный системный вызов socket() . Python же является объектно-ориентированным языком, в нем вместо функций принято использовать классы и их методы. Код модуля socket является ОО-оберткой вокрут набора системных вызовов для работе с сокетами. Его можно представить себе, как:

class socket: # Да, да, имя класса с маленькой буквы :( def __init__(self, sock_familty, sock_type, proto): self._fd = system_socket(sock_family, sock_type, proto) def write(self, data): # на самом деле вместо write используется send, но об этом ниже system_write(self._fd, data) def fileno(self): return self._fd 

Т.е. доступ к целочисленному файловому дескриптору можно получить с помощью:

print(serv_sock.fileno()) # 3 или другой int 

Так мы работаем с серверным сокетом, а в общем случае на серверной машине может быть несколько сетевых адаптеров, нам необходимо привязать созданный сокет к одному из них:

serv_sock.bind(('127.0.0.1', 53210)) # чтобы привязать сразу ко всем, можно использовать '' 

Вызов bind() заставляет нас указать не только IP адрес, но и порт, на котором сервер будет ожидать (слушать) подключения клиентов.

Далее необходимо явно перевести сокет в состояние ожидания подключения, сообщив об этом операционной системе:

backlog = 10 # Размер очереди входящих подключений, т.н. backlog serv_sock.listen(backlog) 

После этого вызова операционная система готова принимать подключения от клиентов на этом сокете, хотя наш сервер (т.е. программа) — еще нет. Что же это означает и что такое backlog?

Как мы уже выяснили, взаимодействие по сети происходит с помощью отправки пакетов, а TCP требует установления соединения, т.е. обмена между клиентом и сервером несколькими служебными пакетами, не содержащими реальных бизнес-данных. Каждое TCP соединение обладает состоянием. Упростив, их можно представить себе так:

СОЕДИНЕНИЕ УСТАНАВЛИВАЕТСЯ -> УСТАНОВЛЕНО -> СОЕДИНЕНИЕ ЗАКРЫВАЕТСЯ 

Таким образом, параметр backlog определяет размер очереди для установленных, но еще не обработанных программой соединений. Пока количество подключенных клиентов меньше, чем этот параметр, операционная система будет автоматически принимать входящие соединения на серверный сокет и помещать их в очередь. Как только количество установленных соединений в очереди достигнет значения backlog, новые соединения приниматься не будут. В зависимости от реализации (GNU Linux/BSD), OC может явно отклонять новые подключения или просто их игнорировать, давая возможность им дождаться освобождения места в очереди.

Теперь необходимо получить соединение из этой очереди:

client_sock, client_addr = serv_sock.accept() 

В отличие от неблокирующего вызова listen() , который сразу после перевода сокета в слушающее состояние, возвращает управление нашему коду, вызов accept() является блокирующим. Это означает, что он не возвращает управление нашему коду до тех пор, пока в очереди установленных соединений не появится хотя бы одно подключение.

На этом этапе на стороне сервера мы имеем два сокета. Первый, serv_sock , находится в состоянии LISTEN , т.е. принимает входящие соединения. Второй, client_sock , находится в состоянии ESTABLISHED , т.е. готов к приему и передаче данных. Более того, client_sock на стороне сервера и клиенсткий сокет в программе клиента являются одинаковыми и равноправными участниками сетевого взаимодействия, т.н. peer’ы. Они оба могут как принимать и отправлять данные, так и закрыть соединение с помощью вызова close() . При этом они никак не влияют на состояние слушающего сокета.

Пример чтения и записи данных в клиентский сокет:

while True: data = client_sock.recv(1024) if not data: break client_sock.sendall(data) 

И опять же справедливый вопрос — где обещанные read() и write() ? На самом деле с сокетом можно работать и с помощью этих двух функций, но в общем случае сигнатуры read() и write() не позволяют передать все возможные параметры чтения/записи. Так, например, вызов send() с нулевыми флагами равносилен вызову write() .

Немного коснемся вопроса адресации. Каждый TCP сокет определяется двумя парами чисел: (локальный IP адрес, локальный порт) и (удаленный IP адрес, удаленный порт) . Рассмотрим, какие адреса на данный момент у наших сокетов:

serv_sock: laddr (ip=, port=53210) raddr (ip=0.0.0.0, port=*) # т.е. любой client_sock: laddr (ip=, port=51573) # случайный порт, назначенный системой raddr (ip=, port=53210) # адрес слушающего сокета на сервере 

Полный код сервера выглядит так:

# python3 import socket serv_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, proto=0) serv_sock.bind(('', 53210)) serv_sock.listen(10) while True: # Бесконечно обрабатываем входящие подключения client_sock, client_addr = serv_sock.accept() print('Connected by', client_addr) while True: # Пока клиент не отключился, читаем передаваемые # им данные и отправляем их обратно data = client_sock.recv(1024) if not data: # Клиент отключился break client_sock.sendall(data) client_sock.close() 

Подключиться к этому серверу можно с использованием консольной утилиты telnet , предназначенной для текстового обмена информацией поверх протокола TCP:

telnet 127.0.0.1 53210 > Trying 192.168.0.1. > Connected to 192.168.0.1. > Escape character is '^]'. > Hello > Hello 

Простейший TCP клиент

На клиентской стороне работа с сокетами выглядит намного проще. Здесь сокет будет только один и его задача только лишь подключиться к заранее известному IP-адресу и порту сервера, сделав вызов connect() .

# python3 import socket client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_sock.connect(('127.0.0.1', 53210)) client_sock.sendall(b'Hello, world') data = client_sock.recv(1024) client_sock.close() print('Received', repr(data)) 

Заключение

Запоминать что-то без понимания, как это работает — злое зло не самый разумный подход для разработчика. Работа с сокетами тому отличный пример. На первый взгляд может показаться, что уложить в голове последовательность приготовления клиентских и серверных сокетов к работе практически не возможно. Это происходит из-за того, что не сразу понятен смысл производимых манипуляций. Однако, понимая, как осуществляется сетевое взаимодействие, API сокетов сразу становится прозрачным и легко оседает в подкорке. А с точки зрения полезности полученных знаний, я считаю. что понимание принципов сетевого взаимодействия жизненно важно для разработки и отладки действительно сложных веб-проектов.

Другие статьи из серии:

  • Пишем свой веб-сервер на Python: процессы, потоки и асинхронный I/O
  • Пишем свой веб-сервер на Python: протокол HTTP
  • Пишем свой веб-сервер на Python: стандарт WSGI
  • Пишем свой веб-сервер на Python: фреймворк Flask

Ссылки по теме

Справочная информация:

Литература

  • Beej’s Guide to Network Programming — отличные основы
  • UNIX Network Programming — продвинутый уровень

Домашний веб-сервер для чайников

Привет, Хабр! Относительно недавно после пары лет перерыва в айти, потраченных на изучение японского языка, мне пришлось срочно обновлять свои знания на работе. Ну знаете, искать возможности исполнить все хотелки начальника, как и положено эникею. Меня ждало много увлекательных открытий, но при этом, как водится, и немало боли и борьбы с непонятками. Docker, контейнеры, реверс DNS и реверс прокси, получение TLS сертификатов. В какой-то момент я наконец дошёл до удобного решения, которым я теперь хочу поделиться.

В своё время домашний сервер очень облегчил бы мне понимание Docker’а, да и удобство работы с ним неслабо бы повысил. Поэтому возникла идея написать эту статью, после прочтения которой любой человек даже с поверхностными знаниями в информационных технологиях сможет поставить себе постоянно доступный домашний сервер на базе Docker Swarm с удобной веб-мордой, простым получением TLS-сертификатов и Heroku-подобным функционалом (для чего будем использовать PaaS CapRover).

Статья, в общем-то, рассчитана на новичков, обладающих какими-то техническими знаниями — школьников старших классов, студентов и просто любителей — а потому вряд ли будет интересна серьёзным профессионалам.

Зачем оно нужно?

Ну как минимум потому что это круто, иметь домашний сервер! Да и настраивать всё это дело интересно. При этом он уже за месяца три отобьёт свою стоимость в сравнении с VPS’ом схожей конфигурации. Ну и наконец он просто радует глаз и миленький.

Что же до использования — иметь возможность развернуть в пару кликов дома Docker-контейнеры сразу в формате http://контейнер.мой.домен/ и в ещё один клик подключить к нему SSL неплохо упрощает жизнь. Сейчас всё больше и больше разнообразных приложений и сервисов переезжают в контейнеры и, если вы не любите лишний раз платить большим компаниям, иметь свои аналоги платных сервисов на домашнем сервере это очень удобно.

Ну а удобство для разработчиков и так понятно.

Подготовка

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

Port Forwarding

Схема работы перенаправления портов

Проверьте наличие у вашего маршрутизатора (роутера) опции Fort forwarding/Port mapping/Перенаправление портов. Это не самый безопасный, но самый простой способ дать нашему серверу путь во внешний мир. Убедитесь что 80, 443 и 3000 порты у вас ничем не заняты — именно их вы будете прописывать IP адресу вашего сервера. Возможно в будущем, например, если вы захотите поднять почтовый сервер, вам придётся прописать дополнительные порты, но пока нужно только это.

Если проводить аналогию для понимания перенаправления портов, то представьте работу мамы в детстве. По умолчанию охранник туда не пустит, но стоит только сказать волшебную фразу «Я к маме», как строгий охранник уже пускает и говорит куда пройти. Вот и тут так же, с нашим NAT’ом роутера, только вместо «Я к маме» вы говорите порт, на что вас направляют куда надо.

Так же стоит убедиться, что у DHCP вашего роутера есть возможность зарезервировать выданный IP адрес за MAC. Скорее всего ваш сервер будет стоять включённым всё время и не просрочит свой выданный IP адрес, но подстраховаться никогда не бывает лишним. Если нельзя — выпишите машине статичный IP вне зоны выдачи адресов DHCP. Это сложнее и неудобнее, но тоже вариант (Кто-то даже скажет что так даже лучше сделать. Но я сейчас за простоту).

Нету этих опций? Возможно ещё не всё потеряно. Проверьте базу https://dd-wrt.com/support/router-database/ на наличие вашего роутера и есть ли тема по нему на 4pda. Если и там пусто. Ну, либо сворачивайте это руководство, либо пора купить новый роутер.

Домен

Конечно, ничто не мешает нам обращаться к нашему домашнему серверу и напрямую по IP адресу, но делать так не рекомендуется: и не особо безопасно, и запоминать IP адрес не просто, да и если у вас динамический, меняющийся каждый раз как вы заново подключаетесь к интернету, IP адрес, то запоминать его вообще бессмысленно. Ну и наконец, у нас много сервисов планируется, а чтобы к ним доступ был тупо по IP адресу, придётся их на разные порты навешивать. Оно вам надо?

Именно поэтому мы будем использовать домен.

Ну, знаете, ту самую штуку, которую вы вводите в адресной строке. В результате сможем давать сервисам поддомены для удобства и не страдать. Ну, например https://пароли.мой.домен/ для парольного сервиса или https://почта.мой.домен/ для почты. Удобно, в общем, запоминается. Делать это будет Ngnix под капотом нашего PaaS, при желании всегда можете разобраться в конкретике.

Схема работы обратного прокси Ngnix в случае контейнеров

Рекомендую я, конечно, домен купить. Цены на домены в популярных зонах достаточно либеральные, платить раз в год, регистраторов куча. В плане выбора регистратора я ничего конкретного советовать не буду. Адекватнее всего ориентироваться по цене и отзывам. Разве что маленькое наблюдение: если регистратор требует миллиарды шекелей за такие вещи, как банальное управление DNS записями, то возможно это не очень хороший регистратор и следует посмотреть в другую сторону.

Впрочем если вы только пощупать пришли, то домен можно получить и бесплатно. Есть такой регистратор — Freenom, там можно бесплатно достать домен в зонах .tk, .ml, .ga, .cf или .gq. Правда как часто бывает с чем-то бесплатным, сайт глючный. Если на проверке доменов у вас всё время пишется, что домен занят, попробуйте поставить сразу полный путь. То есть вводите в проверочное поле не мой_домен, а сразу, скажем, мой_домен.tk.

Очевидно, что если что-то досталось бесплатно, то и потерять его легко — отзывы у Freenom в этом плане далеки от хороших. Так что если планируете что-то серьёзное, то лучше домен себе всё-таки купить у регистратора. Однако для маленького домашнего сервера потенциальная потеря домена не критична.

Cloudflare

Тут мы уже входим в пространство вкусовщины. Вам ничто не мешает использовать и редактор DNS записей вашего регистратора или любой другой сервис управления DNS записями домена. Тут, на хабре, вон вообще CloudFlare раком интернета недавно называли. Но с другой стороны, CloudFlare даже в базовой, бесплатной версии имеет достаточно много приятных фишек, которые ваш регистратор скорее всего не предоставляет. Тут и какая-никакая защита от DDoS, кеширование, расширенные возможности управления доступом и так далее и в том же духе. Плюс в одном из следующих пунктов, когда мы поднимем контейнер для DDNS, будет использоваться именно CloudFlare (впрочем настроить DDNS с другим провайдером вроде DuckDNS — задача достаточно тривиальная).

Правда многие фишки пройдут мимо нас, поскольку проксирование у CloudFlare на wildcard-записи (ну, это записи включающие всё пространство имён *.мой.домен) не работает (ну, за бесплатно). Однако ничего не мешает потом, уже для отдельных сервисов, сделать конкретную запись и пожать все плюшки платформы. Ну или ещё лучше, если у вас статический IP адрес, вообще без DDNS обойтись.

Платформа

Физический путь

Удобство физического пути очевидно — стоит отдельная машинка, не мешает основной работе, радует глаз.

Если спросить, что же использовать как платформу, наверняка многие ответят Малинку (то есть Raspberry Pi). На мой взгляд это не самый лучший выбор для данного случая.

Raspberry Pi отлично подходят для самодельных решений разнообразной направленности, но по соотношению цена/производительность не являются каким-либо лидером. И, хотя сейчас уже множество софта доступно под ARM системы, под x86 программы всё-таки чувствуют себя постабильнее.

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

Я же советовал бы купить для данных целей недорогой (или не очень дешёвый, если вы хотите постоянно запускать «тяжёлые» задачи на вашем сервере) мини-пк (иначе называемый неттоп). Доступные варианты с 8 гигабайтами оперативной памяти, четырёхядерным Celeron и SSD на 128 гигабайт можно найти за 150-200 долларов и этого более чем хватит для домашних задач. При этом он будет компактным, тихим, удобным в размещении, достаточно приятно выглядящим и с низким TDP. Даже в самые дешёвые модели обычно можно доставить как минимум один, а порой и два 2,5 дюймовых диска, так что как файловую помойку его, в общем-то, тоже можно использовать. Хотя лучше превратить его в личное облако, а как файловый сервер использовать отдельное NAS-устройство — для отказоустойчивого хранения большого количества данных форм фактор мини-пк не слишком располагает.

Помимо этого, если вы «наиграетесь» и решите, что оно не ваше, такому компьютеру будет легко найти место. Например поставить обратно Windows и отдать маме/тёте Вале из третьего подъезда. Для офисной работы и использования браузера он подойдёт прекрасно.

А если вы за чуточку большую цену взяли мини-пк с несколькими сетевыми портами, то сможете превратить его в невероятно мощный и функциональный маршрутизатор, поставив сверху OpenWRT, PFsense, ClearOS или ещё какую-нибудь систему для роутеров. Ну и вообще альтернатив много, когда и если наиграетесь с предложенным мной вариантом.

Сразу, правда, надо учесть: шансы, что у такой машинки не будет работать Wi-Fi под линуксом, мягко говоря, не самые маленькие. Так что планируйте проводное соединение.

Заранее погуглите, на какую клавишу вызвать boot menu у вашей машинки. А образ для установки, если вы на Windows, лучше всего на флешку записывать программой Rufus.

Виртуальный путь

Если у вас есть просто живой интерес к тому, что и как настроить, определиться надо ли оно или не надо, то настраиваем виртуальную машину.

Тут стоит провести некоторое разграничение в понимании, поскольку дальше у нас будут ещё и контейнеры Docker. Внешне и по структуре они очень похожи, но вот по использованию неплохо так различаются.

Виртуальная машина — это именно то, как оно звучит — компьютер, которой на самом деле не существует, живущий внутри нашего. Её в какой-то мере можно сравнить с картонной коробкой. Её нужно где-то достать, развернуть, заполнить. Она стоит и занимает место, даже если не до конца заполнена. И залезть внутрь этой коробки иначе как сверху достаточно проблематично.

А контейнер — это как пакетик из магазина. Вроде и служит примерно той же цели, что и коробка, но внутрь что-то положить и достать проще, укладывать по-особому не нужно,места много не занимает, и выкинуть не жалко, и продырявить просто. Говоря же чуть более нормальным языком — контейнер это такая недо-виртуалка, которая ведёт себя скорее как процесс программы.

Конкретный гипервизор (ну, программа, где ваши виртуальные машины создаются и управляются) — на ваше усмотрение. Лучше, конечно, использовать гипервизор первого типа (они, как правило, быстрее, поскольку работают “под” операционной системой, а не “над” ней, как гипервизоры второго типа), но нашему серверу это не очень критично.

Внимание, любители всяких игруль, мобильных и не очень, на Windows — большая часть гипервизоров конфликтуют с эмуляторами Android для игр и с некоторыми античит решениями. Нормально только Bluestacks для Hyper-V работает, так что заранее выберите, что вам важнее.

VirtualBox

Для начала распишу для VirtualBox, который доступен на всех основных платформах, хотя и не отличается высокой скоростью.

Нажмите на кнопку New (Создать) для создания новой машины, и, ориентируясь по своей логике, задайте все настройки — если что, то потом всегда сможете поправить. Правда, меньше чем 2 гигабайта оперативной памяти лучше не ставить.

После создания машины войдите в её настройки. В разделе Storage (Носители) добавьте ваш образ к дисководу (синяя иконка), а в разделе Network (сеть) поменяйте тип подключения на Bridged Adapter (Сетевой мост) и выберите сетевую карту, по которой к вам приходят интернеты, после чего сохраните.

Hyper-V

Поскольку сам я в основном пользуюсь Windows, то предпочитаю использовать Hyper-V — встроенный в Pro версию системы гипервизор первого типа. Если вы пользователь Windows, то вам я тоже его советую — как и положено гипервизору первого типа, он весьма радует своей производительностью.

Чтобы использовать Hyper-V, активируйте его в Turn Windows Features on or off (Включение или отключение компонентов Windows) и перезагрузите компьютер. Вероятно, вам ещё придётся включить аппаратную виртуализацию в BIOS, если вы ещё не делали это. Также необходимо создать в Hyper-V manager (Диспетчер Hyper-V) сетевой интерфейс, ведущий во внешнюю сеть. Кликните справа на Virtual Switch Manager (Диспетчер виртуальных коммутаторов), выберите External (Внешний) и нажмите Create Virtual Switch (Создать виртуальный коммутатор). Далее в настройках External Network (Внешняя сеть) выберите сетевую карту, по которой к вам приходят интернеты, а потом сохраните.

После этого создайте новую машину в Hyper-V manager (но только не создавайте «быструю» машину, там всё не слава богу), а потом пройдите в её свойства и отключите Secure Boot (если машина 2-ого поколения). Остальные параметры по вкусу, но меньше 2 гигабайт оперативной памяти лучше не ставить. Ну и как сетевой интерфейс, очевидно, нужно поставить свежесозданный.

Установка и настройка системы

При выборе дистрибутива для установки у нас есть некоторый выбор (Но свериться с поддерживаемыми платформами на https://docs.docker.com/engine/install/ не помешает). Официально докер рекомендуется ставить на Ubuntu, я обычно предпочитаю Debian, но нам в целом не принципиально. Однако возможные подводные камни я распишу только для этих двух дистрибутивов.

И да, если можете, то лучше напрямую смотрите инструкции. А то информация в интернете имеет привычку устаревать и есть шанс, что к моменту, как вы это читаете, всё уже десять раз поменялось.

В случае с Ubuntu скачайте Ubuntu Server — на сервере графический интерфейс ни к чему, вы даже не будете подключать к нему монитор после изначальной установки. При установке важный момент — НЕ отмечайте Docker в качестве установки по умолчанию. Иначе он поставится как snap пакет, будет глючить, тупить и вообще, зачем вам лишние проблемы, не дружите со snap’ами, это плохая компания.

После установки системы копипастим по одной эти строчки (вы же уже подключились по SSH, правда ведь? Если нет, то чуть подальше будет инструкция) или вбиваем вручную:

sudo apt-get update sudo apt-get install \ ca-certificates \ curl \ gnupg \ lsb-release curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io

При установке Debian не надо отмечать web server, поскольку в качестве него у нас Nginx внутри контейнера Docker’а с нашим PaaS работать будет.

После установки системы копипастим эти строчки:

sudo apt-get update sudo apt-get install \ ca-certificates \ curl \ gnupg \ lsb-release curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io

В общем скачайте что вам нравится, запишите на флешку при физическом пути, подключите к виртуалке при виртуальном и давайте, устанавливайте по инструкциям.

Помимо того, чтобы вводить команды вручную, вы можете использовать Ansible или другие системы для развёртывания, но данное руководство их проигнорирует, поскольку ничего сложного мы не делаем. Просто знайте, что если вам потребуется однотипно настраивать несколько машин, то можно по ssh удобненько это делать через Ansible. Но ssh игнорировать всё же не стоит, ведь как минимум подключившись к своей машине по нему, вы сможете тупо копипастить все команды из руководств, а не вводить вручную.

Ansible это достаточно важный инструмент для Linux-админа и, если вы планируете сдавать или хотя бы просто учиться на сертификации от RedHat, то он вам понадобится. Ну так, на будущее.

Ssh клиентов великое множество, я обычно пользуюсь встроенным в Windows OpenSSH (хотя он встроен, но в старых версиях Windows 10 может быть по-умолчанию отключен. Включается в Turn Windows Features On and Off (Управление дополнительными компонентами)). Просто открываете PowerShell и пишите:

ssh логин_в_linux@IPшник_сервера

А после вводите пароль своего пользователя. Тут стоит отметить, что использовать ssh с паролем это не особо безопасно (но зато проще всего), и, если у вас будет желание с этим разобраться, то лучше настроить ssh ключ.

Систему мы настроили, но не спешите ставить CapRover. Сначала вернёмся к роутеру. Найдите в нём ваш сервер и зарезервируйте его IP адрес в DHCP. Ну или поменяйте его на что-нибудь приятное и зарезервируйте. У вас есть чувство прекрасного, я уверен. После этого пропишите перенаправление с 80, 443 и 3000 портов маршрутизатора на 80, 443 и 3000 порты нашего сервера.

Вот пример того, как оно выглядит в моём роутере TP-Link:

Теперь идём к домену. Войдите в CloudFlare или DNS редактор вашего регистратора и создайте следующую запись:

Тип: A
Хост: *.ваш.домен
Запись: указывает на ваш внешний IP адрес

Если вы не знаете как узнать ваш внешний IP адрес, то посмотрите в настройках интерфейса, роутера, где угодно. Ну или наберите в поисковике что-нибудь вроде «мой IP», если копаться не хочется.

Можете сразу не отходя от кассы создать токен, если планируете динамически обновлять DNS при изменении вашего IP адреса.

Для этого пройдите по ссылке https://dash.cloudflare.com/profile/api-tokens и создайте токен со следующими свойствами:

Zone — Zone Settings — Read
Zone — Zone — Read
Zone — DNS — Edit

Include — All zones

Сохраните длинный Cloudflare API токен, но далеко не убирайте.

Всё, теперь заходим на сервер и пишем волшебную команду, которая поднимает нашу систему для управления контейнерами:

docker run -p 80:80 -p 443:443 -p 3000:3000 -v /var/run/docker.sock:/var/run/docker.sock -v /captain:/captain caprover/caprover

Если вы плохо знакомы с Docker’ом, то тут мы запускаем наш первый контейнер — небольшой PaaS CapRover. Помимо этого мы даём портам в контейнере путь на волю (-p 80:80 -p 443:443 -p 3000:3000), позволяем контейнеру иметь доступ к демону Docker на хост-машине (-v /var/run/docker.sock:/var/run/docker.sock) и делаем так, чтобы папка из контейнера хранила своё содержимое в папке на хосте (-v /captain:/captain). Если так не сделать, то при перезапуске контейнера всё содержимое: настроечные файлы и другие данные нашего контейнера, потеряются навсегда. Так что никогда не забывайте указывать команду -v при работе docker в консоли, чтобы потом не плакать у разбитого корыта. Ну а caprover/caprover — это образ на Docker Hub.

Подождите немного и зайдите либо по айпи адресу, либо по адресу вашего домена:3000 (например http://мой.домен:3000), введите пароль captain42 . После этого тут же введите в нижнее поле ваш домен и нажмите Update Domain. Можете также нажать на Enable HTTPS, но вот на Force HTTPS не надо нажимать — Cloudflare и так трафик у вас (если вы оставили рекомендуемые настройки) с http на https переводит. Конфликтов на этом поводе нам не надо.

Настала пора запустить наш первый контейнер внутри PaaS.

Перейдите в веб панели в раздел Apps, нажмите на One-Click Apps/Database, найдите CloudFlare DDNS. Это достаточно простой контейнер, весь смысл которого сводится к тому чтобы раз в пять минут проверять, изменился ли IP адрес сервера, и, если изменился, обновлять DNS запись на CloudFlare.

После того как вы нажали на него, вы увидите много опций для ввода. Вообще говоря, чтобы всё заработало нам достаточно просто указать наш сохранённый токен CloudFlare и задать какое-нибудь имя. Но давайте всё-таки разберёмся, что именно мы видим.

А видим мы опции ввода так называемых переменных окружения. Не всех правда, а только тех, которые указал автор конфигурационного файла для CapRover. Значения из этих переменных контейнер может достать и использовать в своих целях, проще говоря через них задаётся начальная конфигурация контейнера.

Так вот, задайте какое-нибудь имя, вставьте ранее сохранённый токен и нажмите Deploy. Контейнер заработал. Теперь можете делать что угодно!

Чуть сложнее

Этот контейнер был простым, без веб доступа, но что у тех, к которым мы будем иметь доступ? Да в общем всё так же, разве что ещё можно включить https, задать домен, указать HTTP порт контейнера и включить websocket. Попробуйте, это просто и интересно!

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

И вот наконец у нас всё стоит и работает.

Зачем оно вам? Ну, если вы до сих пор не знаете — придумайте. Для установки в один клик в CapRover доступно множество приложений для повседневного использования. Например менеджер паролей Vaultwarden. Торрент-клиент Qbittorrent. Сервер Minecraft. Боты для Discord. Вариантов много.

Я, например, держу стол для игры в DnD с друзьями Foundry VTT, веб-интерфейс для пробуждение от спячки моего домашнего компьютера (чтобы потом подключаться по RDP), свой маленький гит на базе Gitea, удобный фронтэнд для чтения Reddit’а libReddit, веб-архив для закладок и ещё кучу всякой всячины для тестов и изучения.

Ничто не мешает вам самому поэкспериментировать с контейнерами, которых в списке ещё нет, а если результат будет удовлетворительным — опубликовать свой конфиг на Github среди других приложений для установки в один клик.

В самом начале мы установили SSH, так что если вы захотите более тонкой настройки, подключите и тыкайтесь. Советую также зайти на SSH через VS Studio Code с установленным расширением Docker’а, и установить его же сразу там на ваш сервер. Теперь наблюдать, управлять и чистить мусор в контейнерах гораздо удобнее.

Что дальше?

Возможно, вам уже хватило, вы поняли что это не ваше и вообще. Тоже неплохой результат. Возможно, вы просто хотели домашний сервер и получили его — опять же, к результату мы пришли. Или же вы хотите большего — и это тоже прекрасный результат! Надо понимать, что хотя Docker Swarm уже несколько протух, для небольших нагрузок, вроде домашнего использования, он подходит на отлично. А если вам мало, то, разобравшись как и что тут работает, вы можете медленно начать своё движение к изучению kubernetes.

Что можно посоветовать конкретного? Ну, если Docker вам интересен и хочется в нём разобраться поглубже, то вводный цикл статей от Microsoft достаточно приятно и наглядно объясняет как и что оно.

Если хотите покрупнее брать — и в Hyper-V получше разобраться, и в контейнерах и чуточку затронуть кубер, то вот ещё у них есть неплохие материалы.

Не, не, вы не подумайте, я хоть и виндовый админ (ну хорошо-хорошо, эникей а не админ), но не сказать чтобы прям топлю за Microsoft, просто материалы у них бесплатные и достаточно толковые, на мой взгляд.

Коли от Microsoft тошнит — ищите курсы. В англоязычных интернетах с этим проще — идёшь на Udemy или Pluralsight и выбираешь курс по теме, где люди поменьше в комментах бугуртят на качество, и в бой. С русскоязычными курсами посложнее в выборе, но кто ищет — тот найдёт.

Ну и наконец если в целом вся эта тема с сервисами на своём домашнем сервере вам интересна, то вот отличный список selfhosted решений на все случаи жизни.

В общем, да пребудет с вами IT сила!

Как создать свой веб сервер

Данная статья написана мной по мотивам частых вопросов службе поддержки хостинг-провайдера RunWeb.Ru (к которой я имею непосредственное отношение) по тестированию скриптов и настроек Apache на домашнем компьютере. Первоначально этот материал публиковался на сервере RunWeb.Ru и в рассылке «PHP для начинающих». Постепенно он расширялся по мере поступления вопросов от наших пользователей. Когда же набралось достаточно информации, я собрал ее в отдельную статью и решил, что она может быть полезна не только нашим пользователям хостинга, но и остальным жителям сети.

Поводом для статьи послужило желание создать единое руководство для пользователей, которое помогло бы им тестировать скрипты в домашних условиях, а также использовать возможности настроек Apache для дальнейшего использования на нашем сервере.

Пара слов о работе вебсервера

Установив вебсервер, как описано в этой статье, Вы получаете полноценный работающий сервер с полным набором возможностей. Что же это такое, почему теперь можно обращаться к адресу «127.0.0.1» и даже не подключаться к Интернету? Я уверен, новички зададутся и этими вопросами и многими другими. Здесь я хочу немножко объяснить принцип работы вебсерверов и более подробно рассказать о структуре сайтов в сети.

Вы наверняка знаете, что когда Вы набираете адрес в строке броузера, то Вы работаете по протоколу http (hypertext transfer protocol — протокол передачи гипертекста). Это понятно хотя бы по строке адреса — она имеет вид вроде http://www.адрес.ru.

Что же такое протокол? Это набор команд, с помощью которых общаются Ваш компьютер (конкретно Ваш броузер) и вебсервер, к которому Вы обратились. Для создания сайтов очень важно понимать этот момент.

А что представляет собой вебсервер? В первую очередь это компьютер, на котором установлено программное обеспечение, дающее возможность передавать информацию Вам при запросе ее Вашим броузером. Это программное обеспечение и есть устанавливаемый нами Apache, который просто умеет работать по протоколу http. Когда Вы запускаете Apache, в Вашей системе появляется кто-то, кому есть что ответить броузеру при запросе им конкретного адреса. То есть получается, что Вы имеете сервер, на котором храниться сайт (или сайты) и ПО, которое умеет эти сайты передавать броузеру. Вот и общаются они между собой на языке (протоколе) http — броузер и Apache. Броузер запрашивает у Apache файлы, а Apache их ему отдает.

Теперь о том, каким образом выглядят сайты на нашем сервере. Все сайты хранятся в упорядоченном виде, каждый в отдельном каталоге. Сайт, который открывается по адресу «http://127.0.0.1» имеет в качестве корневого каталога «F:\project». Каталог может называться как угодно и является корневым каталогом для этого сайта. Имена каталогов и их соответствие http-адресам записываются в файле конфигурации Apache — «httpd.conf», который мы ниже будем настраивать. Чтобы это понять, представьте, что можно создать каталог «F:\site» и записать в файле «httpd.conf» что это самый настоящий сайт и он должен открываться по адресу «http://127.0.0.2». И это будет работать. (Как это сделать мы изучим позже).

Обычно в корневом каталоге сайта есть еще несколько каталогов — для хранения html файлов (это наш каталог www), для хранения файлов статистики обращений к сайту (это каталог logs) и другие, пока нами по небольшой надобности неиспользуемые (например папка cgi-bin для хранения программ, написанных на языке PERL). Так вот, папка которая умеет хранить html-странички, т.е. наша папка www может также содержать и php-программы. То есть все, что положить в эту папку и будет видно по адресу «http://127.0.0.1». Это значит, что если вы создадите файл «F:\project\www\page.html», то вы его увидите по адресу «http://127.0.0.1/page.html». Создав каталог «F:\project\www\katalog», вы сможете посмотреть на него по адресу «http://127.0.0.1/katalog/».

Кроме того, каждый каталог на сервере может иметь т.н. «индексный файл». Это файл, который открывается по умолчанию при вызове каталога, т.е. без явного указания имени файла. В нашем случае это index.html, который находиться в корневом каталоге сервера. Набирая «http://127.0.0.1» мы видим именно этот файл. Соответственно, можем также увидеть его, набрав «http://127.0.0.1/index.html».

Установка вебсервера Apache и языка PHP

Для того, чтобы установить вебсервер на свой компьютер, Вам понадобиться некоторое программное обеспечение. Все ПО, которое мы будем использовать, совершенно бесплатно от рождения и доступно в сети для свободного скачивания. Это, согласитесь, хорошо, особенно, если учесть что бесплатных программ (тем более такого серьезного уровня) для Windows бывает очень немного. Также примечательно, что Вам не придется скачивать пиратские программы и копаться в сети в поиске крэков/серийных номеров и т.п.

Вебсервер Apache

Apache — это программа, которая исполняет функции http-сервера. Именно с ее помощью и будет функционировать вебсервер. Эта программа исполняет все необходимые функции, под ее руководством работает большинство ресурсов сети. Наш не исключение, в силу гибкости и универсальности Apache мы будем использовать именно этот сервер. В дальнейшем Вы увидите, насколько просто использовать эту программу в домашних условиях и насколько широкие возможности она предоставляет. Перед тем, как начать установку сервера, Вам необходимо сразу загрузить Apache. В качестве версии Apache я предлагаю использовать 1.3.12, которая имеет полный набор функции и одновременно не осложнена ненужными на данном этапе усовершенствованиями. К тому же она примерно на 2 Мб меньше, чем более новые версии. Загрузить ее можно прямо с нашего сервера RunWeb.Ru:

Язык программирования PHP

Именно эта программа даст Вам возможность использовать PHP-скрипты на сайтах, созданных в рамках сервера Apache. В качестве версии я советую PHP 4.3.4, как наиболее перспективную и стабильную версию. Кроме того, эта версия содержит богатые возможности по сравнению с предыдущими. Загрузить ее также с сервера хостинг-провайдера RunWeb.Ru:

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

Для работы сервера и всех наших дальнейших проектов целесообразно выделить отдельный диск на Вашем компьютере. Конечно, Вам не придется покупать новый винчестер, нам вполне хватит возможностей виртуального диска. Что такое виртуальный диск? Это имитация жесткого диска в системе. Если Вы знакомы с возможностями MS-DOS, то уже поняли, что я имею в виду. Виртуальный диск имеет свое, отдельное имя в системе (например, диск F:) и в качестве своего корневого каталога использует обычный каталог на основном диске. Создается виртуальный диск следующей командой MS-DOS:

subst F: C:\server

Где F: — это имя виртуального диска, а C:\server — это папка на основном диске, которая и будет корневым каталогом нового диска F. Теперь давайте создадим новый диск. Для этого выполните следующие действия (только для Windows 95-98. Как это делается в других версиях смотрите ниже):

Создайте на диске C: папку «server». Откройте в Windows меню «выполнить», которое находиться кнопке «Пуск» и наберите строчку «subst F: C:\server». При этом должно открыться окно с корневым каталогом Вашего нового диска. Обратите внимание, что как здесь, так и дальше я буду использовать именно диск F: в качестве сервера и папку C:\server в качестве корневого каталога этого диска. Я настоятельно советую Вам использовать именно эти параметры, чтобы в дальнейшем при установке не было путаницы. В следующих примерах я буду исходить из того, что у вас все настроено именно так.

Обратите внимание, что виртуальный диск пропадает после перезагрузки и команду subst нужно выполнить заново. Для того, чтобы не вызывать эту команду каждый раз, нужно записать ее в файл autoexec.bat, который находиться в корневом каталоге системного диска. В этом файле содержится список всех программ, которые необходимо выполнить при загрузке системы. Итак, откройте этот файл в «Блокноте» и запишите в самый конец такую строку:

subst F: C:\server

Однако на некоторых операционных системах это может не пойти (например, Windows ME, XP. ). Это связано с принадлежностью файла autoexec.bat системе MS-DOS, а в поздних версиях Windows ее попросту нет. В этом случае сделайте следующее. Создайте файл «subst.bat» и запишите в него всего одну, все ту же строку «subst F: C:\server». Теперь поместите этот файл в корневом каталоге и добавьте его ярлык в автозагрузку. Такой подход приведет к исполнению командного файла subst.bat при каждом запуске Windows. Но здесь появится и неприятный момент. При запуске файла должно открываться окно эмуляции MS-DOS, в котором будет выполняться файл. Не очень удобно закрывать это окошко при каждом запуске системы. Так что может быть лучше отдельно при необходимости запускать файл subst.bat.

Все готово? Тогда давайте продолжим установку. Первое, что нам необходимо сделать — это установить вебсервер Apache. Программа, которую Вы загрузили, является установщиком и сама копирует все необходимые файлы. Однако дальше не все так гладко и не достаточно будет просто завершить все шаги установки. Чтобы установить сервер именно так, как нам требуется, давайте действовать следующим образом.

Установка Apache

Запускаем файл установки Apache. После запуска установщика нажимаем кнопку «NEXT» и «YES», пока не дойдет очередь до указания пути установки. По умолчанию записан путь «C:\Program Files\Apache Group\Apache». Это нас абсолютно не устраивает — нужно установить Apache на свежевыделенный диск F. Для этого нажимаем «Browse» и указываем путь «f:\usr\apache» (если такого каталога нет, система спросит нужно ли его создать, на что отвечайте утвердительно). Почему именно «F:\usr\apache»? Дело в том, что каталог «usr» на сервере является служебным, лежащим отдельно от каталогов, где размещаются файлы сайтов и прочие элементы сервера. Каталог «usr» на сервере — это вроде каталога «Windows\System» в Windows. Далее вы еще столкнетесь с этим каталогом при администрировании вашего сервера. Нажимаем «NEXT», выбираем «Typical» — обычная установка. Ждем еще пару раз «NEXT» и сервер наконец устанавливается на наш компьютер, выполняя копирование файлов. Все! Вы только что установили на свой компьютер персональный вебсервер, на котором можете создавать неограниченное количество сайтов с неограниченными возможностями.

Однако с созданием сайтов мы пока подождем. Перед этим нужно еще установить PHP и много чего настроить в параметрах Вашего сервера. Это несложно — мы не будем сегодня углубляться в серьезные настройки Apache (это, кстати, тема для целой книги!), выполним лишь действия, необходимые и достаточные нам для полноценный работы домашнего сервера.

Установка PHP

Продолжим. Теперь нам нужно установить PHP. Вы имеете файл, загруженный с сервера RunWeb.Ru. Это уже не установщик — это обычный ZIP-архив. Создайте в том же каталоге «F:\usr\» папку «php» и разархивируйте его в получившийся каталог «F:\usr\php».

Теперь посмотрите содержимое каталога «F:\usr\php». Вы видите файл php.exe и наряду с ним папки ddl, extensions, java, Mibs и т.п.? Да? Отлично! Поздравляю, PHP готов исполнять Ваши команды. Осталось только познакомить Apache с PHP — они, кстати, образуют отлично работающую пару.

Настройка сервера Apache и PHP

С установкой программ покончено. Теперь перейдем к их настройке. В первую очередь Вам нужно найти файл «php.ini-dist» в каталоге «F:\usr\php» и скопировать его в папку C:\Windows, причем переименовать его на новом месте в файл «php.ini». В итоге у Вас должен получиться файл «C:\Windows\php.ini». Оставим его как есть, ничего в нем не изменяя и перейдем к настройке Apache. Здесь все немного сложнее.

Открываем файл «F:\usr\apache\conf\httpd.conf» в каком-нибудь текстовом редакторе, например «Блокноте». Это очень важный файл, который содержит все настройки Вашего сервера. В нем необходимо задать несколько параметров. Начнем.

1. Найдите в файле httpd.conf строчку «#ServerName new.host.name». Измените ее на строчку «Servername localhost». Обратите внимание, что знак «#» в начале строки убирается.

2. Далее найдите строчку «DocumentRoot «f:/usr/apache/htdocs» и измените ее на «DocumentRoot «f:/project/www». Обратите внимание на _отсутствие_ слеша в конце.

3. Теперь найдите строчку «» и измените ее на «. Слеш опять отсутствует.

4. Также найдите и измените строку «ErrorLog logs/error.log» на строку «ErrorLog F:/project/logs/error.log» и строку «CustomLog logs/access.log common» на «CustomLog F:/project/logs/access.log common».

5. Теперь перейдите в самый конец файла httpd.conf и впишите в него такие строчки:

ScriptAlias /php/ «f:/usr/php/» AddType application/x-httpd-php .php .phtml .php4 Action application/x-httpd-php «/php/php.exe»

Эти строчки добавляют в настройки Apache возможность выполнения файлов с расширением .php, .phtml или .php4 как программ, написанных на PHP (PHP скриптов).

6. Ну а теперь создайте каталог «F:\project», и в нем два каталога «www» и «logs». В итоге Вы должны получить такое дерево каталогов:

F:\project
F:\project\www
F:\project\logs

Все! Поздравляю, Вы установили и настроили полноценный http-сервер с поддержкой PHP. Теперь дело за малым — научиться включать и выключать сервер, а также немножко его протестировать. Этим мы и займемся далее.

Работа с сервером Apache

При инсталляции сервера программа установки создала в Главном меню (Кнопка «Пуск», далее «Программы») папку «Apache Web Server». В этой папке находиться несколько ярлыков. Нам потребуются следующие из них:

Start Apache — для запуска сервера
Stop Apache — для остановки сервера

При желании Вы можете скопировать их на Рабочий стол, чтобы иметь возможность быстро запускать и выключать сервер.

Двигаемся далее и подходим к самому главному моменту — запуску сервера. Если Вы произвели все указанные действия, то этот этап Вы точно преодолеете без проблем. Но перед запуском я хотел бы предложить Вам сделать еще кое-что, чтобы наверняка протестировать работу вашего сервера.

Итак, создайте в папке «F:\project\www\» файл с именем «index.html» следующего содержания:

 Главная страница сервера Поздравляю Вас, сервер работает! 
Протестируйте PHP: test.php

Создайте там же файл с именем «test.php» такого содержания:

Вот и все, наконец-то можно запускать сервер. Торжественно запускаем ярлык Start Apache. При этом открывается черное окошко вроде окна MS-DOS с единственной надписью «Apache/1.3.12 (Win32) running. «. Это означает, что сервер успешно запущен и на данный момент работает. Окошко закрывать не нужно, оно является рабочей средой Apache и закрывается с помощью ярлыка «Stop Apache», который и выключает сервер.

Итак, сервер запущен. Что дальше? Открывайте ваш броузер и набирайте в нем адрес «http://127.0.0.1». Помните, подключаться к Интернету в этот момент не нужно! Вы должны увидеть уже набранное приветствие, т.е. код файла «index.html». Перейдите по ссылке, ведущей к файлу «test.php». Что вы видите? Броузер должен вывести довольно большой файл с кучей различных обозначений и гордым заголовком «PHP Version 4.3.4» вместе в логотипом PHP. Это — результат работы нашего маленького скрипта «test.php», а точнее функции phpinfo(), которую мы в нем написали. Эта функция выводит все параметры PHP, установленного в системе.

Если Вам все это показалось сложным и непонятным, не пугайтесь. Дальше будет намного проще, просто в первый раз нужно было все установить и настроить, чтобы работало. Сейчас Вы имеете тот необходимый минимум, которого вполне достаточно, чтобы успешно начать работать с сервером.

Отдельно хочу обратиться к продвинутым пользователям, которые, я уверен, читают (или будут читать) мою статью. В первую очередь — если Вы не удовлетворены количеством информации (и объяснений к ней) по поводу настройки Apache и различных директив PHP — не стоит меня сильно в этом обвинять. Моей целью в этой статье было предоставить новичкам стартовую площадку для их обучения и первого проекта. В будущем я постараюсь продолжить эту тему.

Пример: настройка виртуального хоста

В данный момент на созданном сервере есть всего один хост, с уже известным Вам адресом http://127.0.0.1. Однако если у Вас есть несколько сайтов, то не всегда удобно использовать для их отладки один хост. Для подобных целей подойдет возможность Apache использовать несколько виртуальных хостов.

Итак, приступим к созданию виртуального хоста. Как Вы уже знаете, все настройки Apache производятся в файле httpd.conf, который расположен по адресу F:\usr\apache\conf\httpd.conf. В этом файле есть специальный раздел, который обозначен ### Section 3: Virtual Hosts. Он расположен в самом конце файла и отвечает за виртуальные хосты. Далее процесс создания хоста по шагам:

1. Выключите Apache.

2. В самом конце файла httpd.conf допишите такие строчки:

NameVirtualHost 127.0.0.2 ServerAdmin admin@site2 ServerName 127.0.0.2 DocumentRoot "/site2/htdocs/" ScriptAlias /cgi-bin/ "/site2/cgi-bin/" ErrorLog /site2/error.log CustomLog /site2/access.log common 

В данной директиве мы описываем новый хост. Строка VirtualHost 127.0.0.2 обозначает адрес нового хоста. ServerAdmin admin@site2 указывает Email администратора, который будет выводиться при ошибках и служебных сообщениях сервера. ServerName 127.0.0.2 обозначает имя хоста, по которому мы будем к нему обращаться из броузера. DocumentRoot «/site2/htdocs/» указывает директорию, где находятся html и php файлы виртуального сервера. ScriptAlias /cgi-bin/ «/site2/cgi-bin/» указывает каталог, в котором расположены cgi-скрипты (программы на perl, c++ и т.д.). ErrorLog и CustomLog указывают расположение лог-файлов сервера. ErrorLog — это журнал ошибок, CustomLog — журнал доступа. В эти файлы будут записываться все ошибки (например, когда запрошенный файл не существует) и все запросы к серверу.

3. Теперь создайте описанные директории F:\site2\htdocs и F:\site2\cgi-bin. Файлы error.log и access.log можно не создавать, они будут сформированы автоматически при запуске Apache. Директория F:\site2 является корневой директорией виртуального сервера. Обратите внимание, что если Вы не создадите или ошибетесь в именах директорий, то Apache откажется запускаться.

4. Теперь можете запускать Apache. Не забудьте перед этим сохранить изменения в файле httpd.conf.

Вот и все, новый хост создан. Можете разместить в него файлы и просматривать их через броузер по адресу http://127.0.0.2.

Файл настроек .htaccess

Файл .htaccess — это служебный файл вебсервера, с помощью которого можно производить определенные настройки своего сайта. Например, с помощью этого файла можно настроить свои страницы ошибок или обработку SSI-директив.

Файл .htaccess может быть размещен в любом каталоге сервера. Кроме того, он действует на все внутренние каталоги, размещенные в текущей директории. То есть, если у Вас есть каталог «www» и в нем два каталога «1» и «2», то размещая файл .htaccess в «www», Вы одновременно распространяете его действие на каталоги «1» и «2».

Обратите внимание, что имя этого файла начинается с точки. Файлы, имена которых начинаются с точки, в системе Unix являются скрытыми. Это означает, что если Вы загрузите этот файл на сервер провайдера, то Вы не будете видеть его в Вашем FTP-клиенте. Это, кстати, частый вопрос, с которым мы сталкиваемся в службе поддержки RunWeb.Ru. А что делать, если Вы хотите изменить этот файл? Самый простой вариант — изменить его на домашнем компьютере и заново загрузить на сервер по FTP. Ваш клиент не должен спросить перезаписывать ли его, так как он не видит .htaccess в списке файлов. Это нормально, можете быть уверены, файл перепишется.

В качестве примера использования .htaccess давайте рассмотрим установку своих страниц ошибок. Что такое «свои страницы ошибок»? Допустим, у сервера запрашивается документ, которого не существует. В этом случае возникает ошибка номер 404, «Файл не найден». Apache при этом отправляет броузеру свою служебную страницу этой ошибки (404 Not Found). То же самое и с ошибкой номер 500 «Внутренняя ошибка сервера». Она возникает при возникновении ошибки на сервере, например, при исполнении CGI-скрипта. Итак, как установить свои страницы ошибок?

Для этого создайте пустой файл .htaccess в корневом каталоге виртуального хоста (например, F:\server) и запишите в него следующие строки:

ErrorDocument 404 http://127.0.0.1/err404.html
ErrorDocument 500 http://127.0.0.1/err500.html

Они назначают каждой ошибке свою страницу, которая будет открываться при возникновении данной ситуации. Естественно, Вам нужно будет создать файлы err404.html и err500.html на сервере. Называться они могут как угодно, не обязательно как в этом примере.

Существует также много других возможностей настроек файла .htaccess. Несколько очень полезных возможностей (таких как установка индексного файла, паролирование директорий, настройки SSI и другие) описано на нашем сервере RunWeb.Ru в разделе Частые вопросы по настройкам сервера. Список часто пополняется, поэтому рекомендую Вам ознакомиться с описанными в нем возможностями.

Частые вопросы по установке

1. Отсутствуют ярлыки запуска и/или выключения сервера.

Странно, конечно, но и такое, оказывается бывает. В этом случае нужно создать ярлыки для запуска и остановки сервера вручную. Они должны иметь вид:

Запуск сервера: F:\usr\apache\Apache.exe Остановка сервера: F:\usr\apache\Apache.exe -k shutdown

2. Отсутствует файл F:\usr\apache\conf\httpd.conf

Это случается и имеет отношение, равно как и предыдущий пункт, к различным дистрибутивам Apache. (по этому советую загружать дистрибутив, приведенный здесь!). Итак, файл «httpd.conf» отсутсвует, но есть файл «httpd.conf.default». В этом случае нужно скопировать файл «httpd.conf.default» в «httpd.conf» (именно создать копию этого файла с другим именем, а не переименовывать сам файл. «httpd.conf.default» всегда желательно иметь, так как он является дистрибутивом установок Apache и с его помощью Вы всегда можете вернуться к первоначальным настройкам). Ну а дальше производить все настройки в получившемся файле.

3. Не работает PHP (в броузер выводиться код) или не работает Apache (окошко сразу закрывается).

Проверьте правильность установки и настройки сервера (см. выше). Все пути, настройки, тексты скриптов обязательно должны совпадать с примерами — буква в букву. Иначе проблемы скорее всего будут. Например, Вы поставили слеш в настройках в другую сторону (вместо «/» написали «\» или наоборот) или в тексте скрипта вместо »

4. Окно MS-DOS при запуске Apache открывается и сразу же гаснет. Не успеваю даже прочитать, что там написано.

Это означает, что Apache неправильно установлен или настроен. Не стоит сразу же повторять установку (запускать setup) — файлы сервера скопированы верно, ведь ярлык открывает файл Apache.exe. В этом случае обычно неверны настройки сервера. Проверьте файл «httpd.conf» в каталоге «F:\usr\apache\conf\». Особенно внимательно посмотрите на пути (F:\project и т.п.). Не забывайте про слеши! Они должны быть именно такие (в ту сторону), как приведены в примере (см. архив). И, очень важно: там, где их нет (например, в конце путей) не нужно их ставить! В завершение проверьте, что на сервере верна структура каталогов.

Разрешено любое использование при указании авторства.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *