เชชเชพเชธเชตเชฐเซเชก เชตเชฟเชจเชพ MySQL เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชฐเชตเซ‹ (เช…เชจเซ‡ เชธเซเชฐเช•เซเชทเชพ เชœเซ‹เช–เชฎเซ‹)

เชชเชพเชธเชตเชฐเซเชก เชตเชฟเชจเชพ MySQL เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชฐเชตเซ‹ (เช…เชจเซ‡ เชธเซเชฐเช•เซเชทเชพ เชœเซ‹เช–เชฎเซ‹)

เชคเซ‡เช“ เช•เชนเซ‡ เช›เซ‡ เช•เซ‡ เชถเซเชฐเซ‡เชทเซเช  เชชเชพเชธเชตเชฐเซเชก เช เช›เซ‡ เชœเซ‡ เชคเชฎเชพเชฐเซ‡ เชฏเชพเชฆ เชฐเชพเช–เชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชจเชฅเซ€. MySQL เชจเชพ เช•เชฟเชธเซเชธเชพเชฎเชพเช‚ เช† เชชเซเชฒเช—เช‡เชจเชจเซ‡ เช•เชพเชฐเชฃเซ‡ เชถเช•เซเชฏ เช›เซ‡ auth_soket เช…เชจเซ‡ เชฎเชพเชฐเชฟเชฏเชพเชกเซ€เชฌเซ€ เชฎเชพเชŸเซ‡ เชคเซ‡เชจเซเช‚ เชธเช‚เชธเซเช•เชฐเชฃ - เชฏเซเชจเชฟเช•เซเชธ_เชธเซ‹เช•เซ‡เชŸ.

เช† เชฌเช‚เชจเซ‡ เชชเซเชฒเช—เชˆเชจเซ‹ เชฌเชฟเชฒเช•เซเชฒ เชจเชตเชพ เชจเชฅเซ€; เช† เชœ เชฌเซเชฒเซ‹เช—เชฎเชพเช‚ เชคเซ‡เชฎเชจเชพ เชตเชฟเชถเซ‡ เช˜เชฃเซเช‚ เช•เชนเซ‡เชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซเช‚ เช›เซ‡, เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡ เช† เชตเชฟเชถเซ‡เชจเชพ เชฒเซ‡เช–เชฎเชพเช‚ Auth_socket เชชเซเชฒเช—เช‡เชจเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ MySQL 5.7 เชฎเชพเช‚ เชชเชพเชธเชตเชฐเซเชก เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชฌเชฆเชฒเชตเซ‹. เชœเซ‹ เช•เซ‡, เชฎเชพเชฐเชฟเชฏเชพเชกเซ€เชฌเซ€ 10.4 เชฎเชพเช‚ เชจเชตเซเช‚ เชถเซเช‚ เช›เซ‡ เชคเซ‡ เชœเซ‹เชคเซ€ เชตเช–เชคเซ‡, เชฎเซ‡เช‚ เชถเซ‹เชงเซเชฏเซเช‚ เช•เซ‡ เชฏเซเชจเชฟเช•เซเชธ_เชธเซ‹เช•เซ‡เชŸ เชนเชตเซ‡ เชกเชฟเชซเซ‰เชฒเซเชŸ เชฐเซ‚เชชเซ‡ เช‡เชจเซเชธเซเชŸเซ‹เชฒ เช•เชฐเซ‡เชฒเซเช‚ เช›เซ‡ เช…เชจเซ‡ เชคเซ‡ เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃ เชชเชฆเซเชงเชคเชฟเช“เชฎเชพเช‚เชจเซ€ เชเช• เช›เซ‡ ("เชฎเชพเช‚เชฅเซ€ เชเช•", เช•เชพเชฐเชฃ เช•เซ‡ เชฎเชพเชฐเชฟเชฏเชพเชกเซ€เชฌเซ€ 10.4 เชฎเชพเช‚ เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃ เชฎเชพเชŸเซ‡ เชเช• เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชฎเชพเชŸเซ‡ เชเช• เช•เชฐเชคเชพเช‚ เชตเชงเซ เชชเซเชฒเช—เช‡เชจ เช‰เชชเชฒเชฌเซเชง เช›เซ‡, เชœเซ‡ เชฆเชธเซเชคเชพเชตเซ‡เชœเชฎเชพเช‚ เชธเชฎเชœเชพเชตเซ‡เชฒ เช›เซ‡ เชฎเชพเชฐเชฟเชฏเชพเชกเซ€เชฌเซ€ 10.04 เชฎเชพเช‚เชฅเซ€ "เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃ".).

เชฎเซ‡เช‚ เช•เชนเซเชฏเซเช‚ เชคเซ‡เชฎ, เช† เชธเชฎเชพเชšเชพเชฐ เชจเชฅเซ€, เช…เชจเซ‡ เชกเซ‡เชฌเชฟเชฏเชจ เชŸเซ€เชฎ เชฆเซเชตเชพเชฐเชพ เชธเชชเซ‹เชฐเซเชŸเซ‡เชก .deb เชชเซ‡เช•เซ‡เชœเซ‹เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ MySQL เช‡เชจเซเชธเซเชŸเซ‹เชฒ เช•เชฐเชคเซ€ เชตเช–เชคเซ‡, เชธเซ‹เช•เซ‡เชŸ เช“เชฅเซ‡เชจเซเชŸเชฟเช•เซ‡เชถเชจ เชฎเชพเชŸเซ‡ เชฐเซ‚เชŸ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชฌเชจเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡. เช† MySQL เช…เชจเซ‡ MariaDB เชฌเช‚เชจเซ‡ เชฎเชพเชŸเซ‡ เชธเชพเชšเซเช‚ เช›เซ‡.

root@app:~# apt-cache show mysql-server-5.7 | grep -i maintainers
Original-Maintainer: Debian MySQL Maintainers <[email protected]>
Original-Maintainer: Debian MySQL Maintainers <<a href="mailto:[email protected]">[email protected]</a>>

MySQL เชฎเชพเชŸเซ‡ เชกเซ‡เชฌเชฟเชฏเชจ เชชเซ‡เช•เซ‡เชœเซ‹ เชธเชพเชฅเซ‡, เชฐเซเชŸ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพเชจเซ‡ เชจเซ€เชšเซ‡ เชชเซเชฐเชฎเชพเชฃเซ‡ เชชเซเชฐเชฎเชพเชฃเชฟเชค เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡:

root@app:~# whoami
root=
root@app:~# mysql
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 4
Server version: 5.7.27-0ubuntu0.16.04.1 (Ubuntu)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

mysql> select user, host, plugin, authentication_string from mysql.user where user = 'root';
+------+-----------+-------------+-----------------------+
| user | host      | plugin | authentication_string |
+------+-----------+-------------+-----------------------+
| root | localhost | auth_socket |                       |
+------+-----------+-------------+-----------------------+
1 row in set (0.01 sec)

เชฎเชพเชฐเชฟเชฏเชพเชกเซ€เชฌเซ€ เชฎเชพเชŸเซ‡เชจเชพ .deb เชชเซ…เช•เซ‡เชœเชจเซเช‚ เชชเชฃ เชเชตเซเช‚ เชœ เช›เซ‡:

10.0.38-MariaDB-0ubuntu0.16.04.1 Ubuntu 16.04

MariaDB [(none)]> show grants;
+------------------------------------------------------------------------------------------------+
| Grants for root@localhost                                                                      |
+------------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED VIA unix_socket WITH GRANT OPTION |
| GRANT PROXY ON ''@'%' TO 'root'@'localhost' WITH GRANT OPTION                                  |
+------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

เช…เชงเชฟเช•เซƒเชค Percona เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€เชฎเชพเช‚เชฅเซ€ .deb เชชเซ‡เช•เซ‡เชœเซ‹ เช“เชฅ-เชธเซ‹เช•เซ‡เชŸ เชนเซ‡เช เชณ เช…เชจเซ‡ Percona เชธเชฐเซเชตเชฐ เชฎเชพเชŸเซ‡ เชฐเซ‚เชŸ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃเชจเซ‡ เชชเชฃ เช—เซ‹เช เชตเซ‡ เช›เซ‡. เชธเชพเชฅเซ‡ เชเช• เช‰เชฆเชพเชนเชฐเชฃ เช†เชชเซ€เช MySQL 8.0.16-7 เชฎเชพเชŸเซ‡ เชชเชฐเช•เซ‹เชจเชพ เชธเชฐเซเชตเชฐ เช…เชจเซ‡ เช‰เชฌเซเชจเซเชŸเซ 16.04:

root@app:~# whoami
root
root@app:~# mysql
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 9
Server version: 8.0.16-7 Percona Server (GPL), Release '7', Revision '613e312'

Copyright (c) 2009-2019 Percona LLC and/or its affiliates
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

mysql> select user, host, plugin, authentication_string from mysql.user where user ='root';
+------+-----------+-------------+-----------------------+
| user | host      | plugin | authentication_string |
+------+-----------+-------------+-----------------------+
| root | localhost | auth_socket |                       |
+------+-----------+-------------+-----------------------+
1 row in set (0.00 sec)

เชคเซ‹ เชœเชพเชฆเซ เชถเซเช‚ เช›เซ‡? เชชเซเชฒเช—เช‡เชจ เชšเช•เชพเชธเซ‡ เช›เซ‡ เช•เซ‡ เช•เซเชฒเชพเชฏเช‚เชŸ เชชเซเชฐเซ‹เช—เซเชฐเชพเชฎ เชšเชฒเชพเชตเชคเชพ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชตเชฟเชถเซ‡ เชฎเชพเชนเชฟเชคเซ€ เชเช•เชคเซเชฐเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ SO_PEERCRED เชธเซ‹เช•เซ‡เชŸ เชตเชฟเช•เชฒเซเชชเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ Linux เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ MySQL เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชธเชพเชฅเซ‡ เชฎเซ‡เชณ เช–เชพเชฏ เช›เซ‡. เช†เชฎ, เชชเซเชฒเช—เช‡เชจเชจเซ‹ เช‰เชชเชฏเซ‹เช— เชซเช•เซเชค เชคเซ‡ เชธเชฟเชธเซเชŸเชฎเซ‹ เชชเชฐ เชœ เชฅเชˆ เชถเช•เซ‡ เช›เซ‡ เชœเซ‡ SO_PEERCRED เชตเชฟเช•เชฒเซเชชเชจเซ‡ เชธเชชเซ‹เชฐเซเชŸ เช•เชฐเซ‡ เช›เซ‡, เชœเซ‡เชฎ เช•เซ‡ Linux. SO_PEERCRED เชธเซ‹เช•เซ‡เชŸ เชตเชฟเช•เชฒเซเชช เชคเชฎเชจเซ‡ เชธเซ‹เช•เซ‡เชŸ เชธเชพเชฅเซ‡ เชธเช‚เช•เชณเชพเชฏเซ‡เชฒ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเชจเซ€ uid เชถเซ‹เชงเชตเชพ เชฎเชพเชŸเซ‡ เชชเชฐเชตเชพเชจเช—เซ€ เช†เชชเซ‡ เช›เซ‡. เช…เชจเซ‡ เชชเช›เซ€ เชคเซ‡ เชชเชนเซ‡เชฒเชพเชฅเซ€ เชœ เช† uid เชธเชพเชฅเซ‡ เชธเช‚เช•เชณเชพเชฏเซ‡เชฒ เชฏเซเชเชฐเชจเซ‡เชฎ เชฎเซ‡เชณเชตเซ‡ เช›เซ‡.

เช…เชนเซ€เช‚ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ "vagrant" เชธเชพเชฅเซ‡เชจเซเช‚ เช‰เชฆเชพเชนเชฐเชฃ เช›เซ‡:

vagrant@mysql1:~$ whoami
vagrant
vagrant@mysql1:~$ mysql
ERROR 1698 (28000): Access denied for user 'vagrant'@'localhost'

MySQL เชฎเชพเช‚ เช•เซ‹เชˆ "เชตเซ‡เช—เซเชฐเชจเซเชŸ" เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชจ เชนเซ‹เชตเชพเชฅเซ€, เช…เชฎเชจเซ‡ เชเช•เซเชธเซ‡เชธ เชจเช•เชพเชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡. เชšเชพเชฒเซ‹ เช†เชตเชพ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชฌเชจเชพเชตเซ€เช เช…เชจเซ‡ เชซเชฐเซ€ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ€เช:

MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'vagrant'@'localhost' IDENTIFIED VIA unix_socket;
Query OK, 0 rows affected (0.00 sec)

vagrant@mysql1:~$ mysql
Welcome to the MariaDB monitor.  Commands end with ; or g.
Your MariaDB connection id is 45
Server version: 10.0.38-MariaDB-0ubuntu0.16.04.1 Ubuntu 16.04
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

MariaDB [(none)]> show grants;
+---------------------------------------------------------------------------------+
| Grants for vagrant@localhost                                                    |
+---------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'vagrant'@'localhost' IDENTIFIED VIA unix_socket |
+---------------------------------------------------------------------------------+
1 row in set (0.00 sec)

เชฅเชฏเซเช‚!

เชธเชพเชฐเซเช‚, เชฌเชฟเชจ-เชกเซ‡เชฌเชฟเชฏเชจ เชตเชฟเชคเชฐเชฃ เชตเชฟเชถเซ‡ เชถเซเช‚ เชœเซเชฏเชพเช‚ เช† เชกเชฟเชซเซ‰เชฒเซเชŸ เชฐเซ‚เชชเซ‡ เชชเซเชฐเชฆเชพเชจ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเชคเซเช‚ เชจเชฅเซ€? เชšเชพเชฒเซ‹ CentOS 8 เชชเชฐ เชธเซเชฅเชพเชชเชฟเชค MySQL 7 เชฎเชพเชŸเซ‡ Percona เชธเชฐเซเชตเชฐเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ€เช:

mysql> show variables like '%version%comment';
+-----------------+---------------------------------------------------+
| Variable_name   | Value                                   |
+-----------------+---------------------------------------------------+
| version_comment | Percona Server (GPL), Release 7, Revision 613e312 |
+-----------------+---------------------------------------------------+
1 row in set (0.01 sec)

mysql> CREATE USER 'percona'@'localhost' IDENTIFIED WITH auth_socket;
ERROR 1524 (HY000): Plugin 'auth_socket' is not loaded

เชฌเชฎเชฐ. เชถเซเช‚ เช–เซ‚เชŸเชคเซเช‚ เชนเชคเซเช‚? เชชเซเชฒเช—เช‡เชจ เชฒเซ‹เชก เชฅเชฏเซ‡เชฒ เชจเชฅเซ€:

mysql> pager grep socket
PAGER set to 'grep socket'
mysql> show plugins;
47 rows in set (0.00 sec)

เชšเชพเชฒเซ‹ เชชเซเชฐเช•เซเชฐเชฟเชฏเชพเชฎเชพเช‚ เชชเซเชฒเช—เช‡เชจ เช‰เชฎเซ‡เชฐเซ€เช:

mysql> nopager
PAGER set to stdout
mysql> INSTALL PLUGIN auth_socket SONAME 'auth_socket.so';
Query OK, 0 rows affected (0.00 sec)

mysql> pager grep socket; show plugins;
PAGER set to 'grep socket'
| auth_socket                     | ACTIVE | AUTHENTICATION | auth_socket.so | GPL     |
48 rows in set (0.00 sec)

เชนเชตเซ‡ เช†เชชเชฃเซ€ เชชเชพเชธเซ‡ เชœเชฐเซ‚เชฐเซ€ เชฌเชงเซเช‚ เช›เซ‡. เชšเชพเชฒเซ‹ เชซเชฐเซ€เชฅเซ€ เชชเซเชฐเชฏเชคเซเชจ เช•เชฐเซ€เช:

mysql> CREATE USER 'percona'@'localhost' IDENTIFIED WITH auth_socket;
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT ALL PRIVILEGES ON *.* TO 'percona'@'localhost';
Query OK, 0 rows affected (0.01 sec)

เชคเชฎเซ‡ เชนเชตเซ‡ "percona" เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพเชจเชพเชฎเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชฒเซ‰เช— เช‡เชจ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹.

[percona@ip-192-168-1-111 ~]$ whoami
percona
[percona@ip-192-168-1-111 ~]$ mysql -upercona
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 19
Server version: 8.0.16-7 Percona Server (GPL), Release 7, Revision 613e312

Copyright (c) 2009-2019 Percona LLC and/or its affiliates
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

mysql> select user, host, plugin, authentication_string from mysql.user where user ='percona';
+---------+-----------+-------------+-----------------------+
| user    | host   | plugin   | authentication_string |
+---------+-----------+-------------+-----------------------+
| percona | localhost | auth_socket |                       |
+---------+-----------+-------------+-----------------------+
1 row in set (0.00 sec)

เช…เชจเซ‡ เชคเซ‡ เชซเชฐเซ€เชฅเซ€ เช•เชพเชฎ เช•เชฐเซเชฏเซเช‚!

เชชเซเชฐเชถเซเชจ: เชถเซเช‚ เช เชœ เชชเชฐเซเช•เซ‹เชจเชพ เชฒเซ‰เช—เชฟเชจ เชนเซ‡เช เชณ เชธเชฟเชธเซเชŸเชฎเชฎเชพเช‚ เชฒเซ‰เช— เช‡เชจ เช•เชฐเชตเซเช‚ เชถเช•เซเชฏ เชฌเชจเชถเซ‡, เชชเชฐเช‚เชคเซ เชเช• เช…เชฒเช— เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชคเชฐเซ€เช•เซ‡?

[percona@ip-192-168-1-111 ~]$ logout
[root@ip-192-168-1-111 ~]# mysql -upercona
ERROR 1698 (28000): Access denied for user 'percona'@'localhost'

เชจเชพ, เชคเซ‡ เช•เชพเชฎ เช•เชฐเชถเซ‡ เชจเชนเซ€เช‚.

เชจเชฟเชทเซเช•เชฐเซเชท

MySQL เช˜เชฃเชพ เชชเชพเชธเชพเช“เชฎเชพเช‚ เชคเชฆเซเชฆเชจ เชฒเชตเชšเซ€เช• เช›เซ‡, เชœเซ‡เชฎเชพเช‚เชฅเซ€ เชเช• เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃ เชชเชฆเซเชงเชคเชฟ เช›เซ‡. เชœเซ‡เชฎ เชคเชฎเซ‡ เช† เชชเซ‹เชธเซเชŸเชฎเชพเช‚เชฅเซ€ เชœเซ‹เชˆ เชถเช•เซ‹ เช›เซ‹, OS เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพเช“เชจเชพ เช†เชงเชพเชฐเซ‡, เชชเชพเชธเชตเชฐเซเชก เชตเชฟเชจเชพ เชเช•เซเชธเซ‡เชธ เชฎเซ‡เชณเชตเซ€ เชถเช•เชพเชฏ เช›เซ‡. เช† เชšเซ‹เช•เซเช•เชธ เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟเช“เชฎเชพเช‚ เช‰เชชเชฏเซ‹เช—เซ€ เชฅเชˆ เชถเช•เซ‡ เช›เซ‡, เช…เชจเซ‡ เชคเซ‡เชฎเชพเช‚เชฅเซ€ เชเช• เชœเซเชฏเชพเชฐเซ‡ RDS/Aurora เชฅเซ€ เชจเชฟเชฏเชฎเชฟเชค MySQL เชฎเชพเช‚ เชธเซเชฅเชพเชจเชพเช‚เชคเชฐเชฟเชค เชฅเชพเชฏ เช›เซ‡ IAM เชกเซ‡เชŸเชพเชฌเซ‡เช เชชเซเชฐเชฎเชพเชฃเซ€เช•เชฐเชฃเชนเชœเซ เชชเชฃ เชเช•เซเชธเซ‡เชธ เชฎเซ‡เชณเชตเชตเชพ เชฎเชพเชŸเซ‡, เชชเชฐเช‚เชคเซ เชชเชพเชธเชตเชฐเซเชก เชตเชฟเชจเชพ.

เชธเซ‹เชฐเซเชธ: www.habr.com

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹