понедельник, 19 декабря 2022 г.

Debian 11, включить модуль Apache rewrite

Источник: этот

Шаг 1. Активируем mod_rewrite
sudo a2enmod rewrite
sudo systemctl restart apache2


Шаг 2. Разрешаем использование файла .htaccess
sudo nano /etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
    <Directory /var/www/html>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    . . .
</VirtualHost>

Шаг 3. Проверяем корректность конфигурационного файла 
sudo apache2ctl configtest

Шаг 4. Перезапускаем службу Apache
sudo systemctl restart apache2

Шаг 5. В корне нашего web-сайта создаём файл `.htaccess`, и пишем в него две строки
sudo nano /var/www/html/.htaccess

Options +FollowSymLinks
Redirect /test.html http://7d3.ru


Страницу "test.html" не создаем. При попытке открыть страницу /test.html если переадресованы на 7d3.ru, значит .htaccess работает.

суббота, 10 декабря 2022 г.

C# dotnet 4.7.2 std - Асинхронный запрос к web-ресурсу (HttpClient, POST-метод, FilesAttach)

            Класс: CustomWebRequest_v3
         Копирайт: Виктор Туляков, дек-2022
       Назначение: Выполнение web-запроса
    Метод запроса: POST
 Доп. возможность: Прикрепление нескольких файлов

Пример использования:

...

private async void button1_Click_1(object sender, EventArgs e)
{
    CustomWebRequest_v3 webReq = 
                                new CustomWebRequest_v3(
                                          "http://192.168.0.101/engine/");

    webReq.event_msg = log;

    Task<string> getReq = webReq.SendCommand(new Dictionary<string, string> {
            { "script", "index"},
            { "key2", "value2"},
            { "key3", "value3"}
        },
        // вторым аргументом крепим файлы, используя new string[] {}
        // если файлы не крепим, то используем метод SendCommand с одним 
        // аргументом new Dictionary<string, string>{{"param", "value"}, ...}
        new string[] { @"d:\image1.jpg", @"d:\journal.txt" });

    string resp = "";

    resp = await getReq;

    if (resp == null)
    {
        log("Ошибка выполнения запроса.");
        return;
    }

    log(resp);
    log();
    log(webReq.lastRequest_DurationInSecond.ToString());
}

private void log(string msg = "")
{
    // Компонент TextBox для отображения событий от класса 'CustomWebRequest_v3'
    tbLog.AppendText(msg + "\r\n");
}

...



-------------------------------------------------------------
Скачать класс: CustomWebRequest_v3.cs

пятница, 9 декабря 2022 г.

Настройка https в Apache

 Источник: https://help.ubuntu.ru/wiki/apache_%D0%B8_https

Создание ключа и ssl-сертификата

Использование самоподписанных сертификатов хоть и защищает от пассивного прослушивания, тем не менее не гарантирует клиентам, что сервер является именно тем сервером, который им нужен. Преймуществом самоподписанных сертификатов является их бесплатность. Сертификат, подписанных компанией-сертификатором (Certificate authority) стоит денег.

# Для создания ключа и сертификата вводим команду:
openssl req -new -x509 -days 30 -keyout server.key -out server.pem

На вопрос «Enter PEM pass phrase:» отвечаем паролем, подтверждаем и запоминаем. На все последующие вопросы отвечаем произвольно, можно просто щелкать по Enter соглашаясь с предложенными вариантами, только на вопрос «Common Name (eg, YOUR name) []:» отвечаем именем сайта, для которого создаем сертификат, например www.example.com.

После ответа на все вопросы в директории должны появиться два новых файла - server.pem и server.crt (ключ и сертификат, соответственно).

Чтобы использовать сгенерированный ключ нужно знать пароль введенный нами, и Apache будет спрашивать его у нас при загрузке, а к чему нам лишние вопросы от демонов? :) Поэтому снимаем пароль с ключа:

cp server.key{,.orig}
openssl rsa -in server.key.orig -out server.key
rm server.key.orig

Скопируем их в /etc/ssl и назначим файлу ключа права чтения только администратору:

sudo cp server.pem /etc/ssl/certs/
sudo cp server.key /etc/ssl/private/
sudo chmod 0600 /etc/ssl/private/server.key

Шаг 2. Настройка Apache
# Для начала необходимо активировать mod_ssl:
sudo a2enmod ssl

# А затем включить настройки HTTPS сайта по умолчанию:
sudo a2ensite default-ssl

Теперь необходимо отредактировать файл с настройками HTTPS сайта по умолчанию, указав в нём пути к вашим сертификатам. Сам файл называется /etc/apache2/sites-enabled/default-ssl (или /etc/apache2/sites-enabled/default-ssl.conf).

# После дерективы
SSLEngine on

# ...добавляем строку для запрета использования устаревшего протокола SSLv2
SSLProtocol all -SSLv2

# Прописываем публичный сертификат сервера
SSLCertificateFile    /etc/ssl/certs/server.pem

# Прописываем приватный ключ сервера
SSLCertificateKeyFile /etc/ssl/private/server.key

# Перезапускаем Apache:
sudo service apache2 restart

При корректности указания параметров, сайт станет доступен по HTTPS.
Протокол HTTPS работает по 443 порту, поэтому если сервер находится за шлюзом, то необходимо на нём пробросить данный порт.

Шаг 3. Перенаправление HTTP запросов на HTTPS
#Для запрета использования HTTP и перенаправления на HTTPS адрес включаем mod_alias
sudo a2enmod alias
sudo service apache2 restart

В файл /etc/apache2/sites-enabled/000-default, отвечающий за виртуальный хост по умолчанию для HTTP запросов, добавляем директиву
Redirect / https://example.com/

При этом все настройки директорий можно удалить, поскольку по HTTP на ваши сайты всё равно будет не попасть.

Всё, теперь ещё раз перезапустите Apache и убедитесь, что при заходе по HTTP вы автоматически перенаправляетесь на HTTPS страницу.

Debian web-server secure option

 php.ini
allow_url_fopen = Off. Эта настройка отвечает за то, могут ли внешние файлы быть включены в ваш сайт. По умолчанию это разрешено, чтобы это изменить, кликните по флажку.
allow_url_include = Off. Определяет, могут ли встроенные функции ссылаться на файлы, расположенные удаленно на других ресурсах.


P.S. Для того, чтобы сменить идентификатор в php вам нужно воспользоваться session_regenerate_id. В случае, если вы используете PHP 5.2 или выше, то для защиты от угона идентификатора вы можете воспользоваться таким функциями, как: session.cookie.httpolny и session_set_cookie_parms.

Debian web-service tips

 #Узнать локацию файла php.ini
php -i | grep php.ini

воскресенье, 4 декабря 2022 г.

Настройка ОС Debian после установки как web-сервера

Источник: https://losst.pro/ustanovka-lamp-v-debian-9

После окончания установки ОС Debian:

# Отключаем CDROM как репозиторий установки софта, оставляем строки с 'deb', комментируем строку 'cdrom' в фале 
nano /etc/apt/sources.list

# Устаналвиваем `sudo`:
apt install sudo -y

# Обновляем менеджер по работе с пакетами ПО
sudo apt update && sudo apt upgrade

# Устанавливаем Apache с привязкой модулей для работы с php:
sudo apt-get install -y apache2 php php-mysql libapache2-mod-php php-mbstring php-zip php-gd

# Устанавливаем сервер базы данных MariaDB
sudo apt-get -y install mariadb-server mariadb-client mariadb-common

# Каталог для распаложения *.php и *.html -файлов `/var/www/html`
# index.html переименовываем в index.html_
mv /var/www/html/index.html /var/www/html/index.html_

# Создаем index.php
nano /var/www/html/index.php
<?php
    phpInfo();
?>

Настройка удаленного подключения к mysql (mariadb)

1. Создаем пользователя MariaDB

root@servername# sudo mysql -u root -p

mysql> CREATE USER 'user'@'%' IDENTIFIED BY 'your password';
Query OK, 0 rows affected (0.11 sec)

mysql> GRANT ALL ON *.* TO 'user'@'%';
Query OK, 0 rows affected (0.15 sec)

mysql> FLUSH PRIVILEGES;

mysql> quit;



2. Разрешаем подключения с удаленного хоста к серверу MariaDB

nano /etc/mysql/mariadb.conf.d/50-server.cnf

Комментируем
#bind-address = 127.0.0.1

Добавляем
bind-address = 0.0.0.0



3. Перезапускаем сервис mysql

sudo service mysql restart

php move_uploaded_file failed to open stream: Permission denied

При обработке полученного файла php-скриптом (перемещении файла из временного каталога в наш каталог на стороне web-сервера) $_FILES получаем сообщение о недостаточности прав, например, как у меня "<b>Warning</b>:  move_uploaded_file(/var/www/html/upload_files/defect_attach/04_12_22_01_05_41_371_3374.zip): failed to open stream: Permission denied in <b>/var/www/html/engine/defect.php</b> on line <b>159</b><br />"


Шаг 1. Выясняем под каким пользователем выполняется наш php-скрипт на стороне сервера:
<?php echo exec('whoami'); ?>
...в моем случае это "www-data";

Шаг 2. Добавляем пользователя, под которым подключаемся 
к серверу для разработки в группу `www-data`:
sudo adduser <username> www-data

Шаг 3.
sudo chown -R www-data:www-data /var/www

Шаг 4.
sudo chmod -R g+rwX /var/www

вторник, 10 мая 2022 г.

Класс для логирования программы (RichTextBox), версия 2

Первая версия класса расположена по web-ссылке: RichTextBox_LoggedClass

Во вторую версию одноименного класса добавлено:

1. Логирование отладочного текста (*.log_dbg), по умолчанию оранжевого цвета (*.col_dbg). При логировании строки в компоненте RichTextBox не используется (timestamp( )) в начале добавляемого текста и не используются символы перевода строки ("\r\n") в конце текста.

2. Добавление текста в компонент RichTextBox выполнена через *.InvokeRequired, позволяющего работать из другого потока;

3. Также пространство имен в классе "Framework". Исключено имя разрабатываемого проекта (projectname.Framework);
Остальные методы работы остались без изменений:

Пример использования класса:
---------------------
...
using Framework;
...
class Class_Name {
    RichTextBoxLogClass log;
    public Class_Name() {
        log = new RichTextBoxLogClass(rtbLog);
    }
    
    ...
    public void button_click(...) {
        log.log_msg("Начало выполнения операции.");
        log.log_err("Ошибка выполнения операции");
        log.log_tx("ASCII CMD SEND TEXT");
        log.log_rx("ASCII CMD RECIVED TEXT");
        log.log_tx(new byte [] {0x01, 0x20, 0x44, 0x55});
        log.log_rx(new byte [] {0x01, 0x20, 0x44, 0x55});
        log.log_dbg("dbg chars " + BitConverter.ToString(new byte[] {0x01, 0x02, 0x03 }).Replace("-", " ");   
    }
}

Настраиваемые параметры:
------------------------
    log.col_msg - цвет текста сообщения, по умолчанию, Color.Gray;
    log.col_err - цвет текста сообщения об ошибке, по умолчанию, Color.Black;
    log.col_tx - цвет текста отправляемых данных, по умолчанию, Color.Red;
    log.col_rx - цвет текста принимаемых данных, по умолчанию, Color.Blue;
    log.log_dbg - цвет текста отладочного сообщения, по умолчанию, Color.Orange;
    log.timestampFormat - формат вывода времени, например, "HH:mm:ss.ff";
    log.bytes_in_line - количество байт в строке, например, 16;
    log.hex_to_ascii_space - расст между hex и ascii строк, напр. 8;

среда, 4 мая 2022 г.

Сохранение настроек программы в xml-файл

        ...
        string param1;
        string param2;
        string param3;
        bool flag1;
        ...

static class SaveAppSetting
{

    public static string fname_xml = @"\appSetting.xml";
    
    static XmlDocument doc;
    
    static public void LoadXmlAppSetting()
    {
        if (System.IO.File.Exists(fname_xml))
        {
            doc = new XmlDocument();
        
    doc.Load(fname_xml);
        
        
    param1 = getStringValue("/setting/equipment/param1");
            param2 = getStringValue("/setting/equipment/param2");
            param3 = getStringValue("/setting/equipment/param3");
         
            flag1 = getBoolValue("/setting/dbg/log_7e1_codeString");
        }
    }

    static public void SaveXmlAppSetting()
    {
        string xml_content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
                             "<setting>";
        xml_content += "<equipment>";
        xml_content += "<
param1>" + param1 + "</param1>";
        xml_content += "<param2>" + param2 + "</param2>";
        xml_content += "<param3>" + param3 + "</param3>";

        xml_content += "<flag1>" + flag1.ToString() + "</flag1>";
        xml_content += "</equipment>";

        xml_content += "</setting>";
        try
        {
            doc = new XmlDocument();
            doc.LoadXml(xml_content);
            doc.Save(fname_xml);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    static private string getStringValue(string xml_path, string default_value = "-")
    {
        string ret_value = "";
        try
        {
            ret_value = doc.SelectSingleNode(xml_path).InnerText.Trim();
        }
        catch
        {
            ret_value = default_value;
        }
          
        return ret_value;
    }
    
    static private bool getBoolValue(string xml_path, bool default_value = false)
    {
        bool ret_value = false;
        
        try
        {
            ret_value = Convert.ToBoolean(doc.SelectSingleNode(xml_path).
                                                                 InnerText.Trim());
        }
        catch
        {
            ret_value = default_value;
        }
        
        return ret_value;
    }
}

Docker. Первые контейнеры

Источник:  php.dragomano.ru Структура каталогов: ~/develop/web/project/                  nginx/      - сервис web-сервера                php...