Romania XPlayZM.CSBlackDevil.COM # Zombie Plague UltimateX [ Respawn + FDL + VIP 22-12PM + POINTS] ® 30/32
Unknown ❤ RESPAWN.ZAFEST.RO | VIP FREE | FREE FOR ALL ❤ 0/32
France EMIRATES.KiNGS 亗 GAMEAREA ||͇̿P͇̿U͇̿B͇̿L͇̿I͇̿C͇̿| ✪ 32/32
Promover servidor

Add install-mariadb-for-amxx/en.md

Browse Source
C counter-strike-boost.com committed parent 91f4660dc3 commit 6feee27c187edaf578872d859c22d7b72b1a5b6f
1 changed file with 127 additions and 0 deletions
+127 -0 install-mariadb-for-amxx/en.md A
@@ -0,0 +1,127 @@
1 +---
2 +title: "How to Set Up MariaDB for AMX Mod X (Local or Remote)"
3 +excerpt: "Install and secure MariaDB on Debian or Ubuntu for AMX Mod X plugins, choose a same-host or separate-host setup, lock port 3306 to your game server, and back it up with mariadb-dump and cron."
4 +category: "installation"
5 +tags: "mariadb, mysql, amxx, database, firewall, backups"
6 +image: ""
7 +read_time: "7 min read"
8 +---
9 +<p>Stats, bans, shops and VIP plugins all want a MySQL-compatible database, and on Debian or Ubuntu the one to install is MariaDB. It is what the distribution ships, and it still creates users with the <code>mysql_native_password</code> login method, which the MySQL 5.5 client code built into the AMX Mod X module understands. MySQL 8 defaults to a newer login method (<code>caching_sha2_password</code>) that the older client code in the AMX Mod X module may not support, a common reason a fresh MySQL 8 box rejects every plugin. This page covers the database server. The plugin side (the module, <code>sql.cfg</code>, threaded queries) is in <a href="/tutorials/install-mysql-module-amxx">enabling the MySQL module in AMX Mod X</a>.</p>
10 +
11 +<h2>1. Install MariaDB</h2>
12 +<pre><code>sudo apt update
13 +sudo apt install -y mariadb-server
14 +sudo systemctl enable --now mariadb
15 +sudo mariadb -e &quot;SELECT VERSION();&quot;</code></pre>
16 +<p>On Debian and Ubuntu the database <code>root</code> account logs in through the Unix socket: <code>sudo mariadb</code> works with no password because the operating system has already proved you are root. Keep it that way: there is no root password to leak or brute-force.</p>
17 +
18 +<h2>2. Secure the install</h2>
19 +<pre><code>sudo mariadb-secure-installation</code></pre>
20 +<ul>
21 +<li><strong>Enter current password for root:</strong> press Enter.</li>
22 +<li><strong>Switch to unix_socket authentication:</strong> <code>n</code>. The script itself tells you root is already protected.</li>
23 +<li><strong>Change the root password:</strong> <code>n</code>, for the same reason.</li>
24 +<li><strong>Remove anonymous users, Disallow root login remotely, Remove test database, Reload privilege tables:</strong> <code>Y</code> to all four.</li>
25 +</ul>
26 +
27 +<h2>3. Create the database and a least-privilege user</h2>
28 +<p>Generate a password that needs no quoting in <code>sql.cfg</code>:</p>
29 +<pre><code>openssl rand -hex 20</code></pre>
30 +<p>Then, for a database on the same machine as the game server:</p>
31 +<pre><code>sudo mariadb
32 +CREATE DATABASE amxx CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
33 +CREATE USER &#039;amxx&#039;@&#039;127.0.0.1&#039; IDENTIFIED BY &#039;paste-the-generated-password&#039;;
34 +GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX ON amxx.* TO &#039;amxx&#039;@&#039;127.0.0.1&#039;;</code></pre>
35 +<p>Granting to <code>127.0.0.1</code> rather than <code>localhost</code> matters: with <code>amx_sql_host</code> set to <code>127.0.0.1</code> AMXX connects over TCP, and MariaDB matches user and host together, so <code>'amxx'@'localhost'</code> would only cover socket logins. No <code>ALL PRIVILEGES</code>, no <code>root</code>: a plugin you downloaded should not be able to drop the database. If a plugin's upgrade notes say it alters its own tables, grant <code>ALTER</code> for that upgrade and revoke it afterwards.</p>
36 +
37 +<h2>4. Same host or separate host</h2>
38 +<h3>Same host (the default, and the best choice for one server)</h3>
39 +<p>Debian's config already binds MariaDB to loopback only. Confirm nothing listens on the network:</p>
40 +<pre><code>sudo ss -ltnp | grep 3306</code></pre>
41 +<p>You want <code>127.0.0.1:3306</code>. Nothing outside the box can reach it, so port 3306 needs no firewall rule, and queries take well under a millisecond.</p>
42 +
43 +<h3>Separate host (several game servers sharing bans or stats)</h3>
44 +<p>Assume the database box is <code>10.0.0.5</code> and the game server is <code>10.0.0.10</code>. On the database box, edit <code>/etc/mysql/mariadb.conf.d/50-server.cnf</code> and change the <code>bind-address</code> line to the address the game server will connect to, preferably a private network address:</p>
45 +<pre><code>bind-address = 10.0.0.5</code></pre>
46 +<pre><code>sudo systemctl restart mariadb
47 +sudo ss -ltnp | grep 3306</code></pre>
48 +<p>Use <code>0.0.0.0</code> only if there is no private network, and then the firewall below is mandatory. Create the user for the game server's IP, as MariaDB will see it (behind NAT or over the internet, that is the game box's public IP):</p>
49 +<pre><code>CREATE USER &#039;amxx&#039;@&#039;10.0.0.10&#039; IDENTIFIED BY &#039;paste-the-generated-password&#039;;
50 +GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX ON amxx.* TO &#039;amxx&#039;@&#039;10.0.0.10&#039;;</code></pre>
51 +<p>Each additional game server gets its own <code>CREATE USER</code> and <code>GRANT</code> for its IP. On the game server, <code>amx_sql_host</code> becomes <code>10.0.0.5</code>.</p>
52 +<p>Now allow 3306 from the game server only. With ufw (allow your SSH port before enabling it, or you lock yourself out):</p>
53 +<pre><code>sudo ufw allow OpenSSH
54 +sudo ufw allow from 10.0.0.10 to any port 3306 proto tcp
55 +sudo ufw enable
56 +sudo ufw status numbered</code></pre>
57 +<p>If SSH listens on a non-standard port, allow that port number instead of <code>OpenSSH</code>. With plain iptables, the accept rule must come before the drop:</p>
58 +<pre><code>sudo iptables -A INPUT -p tcp -s 10.0.0.10 --dport 3306 -j ACCEPT
59 +sudo iptables -A INPUT -p tcp --dport 3306 -j DROP
60 +sudo apt install -y iptables-persistent
61 +sudo netfilter-persistent save</code></pre>
62 +<p>Two warnings. If MariaDB runs in Docker with a published port, Docker's own rules bypass ufw, so publish it on a specific address (<code>-p 10.0.0.5:3306:3306</code>) instead of all of them. And AMXX's SQL connection has no TLS option, so queries cross the wire in plain text: if the two boxes talk over the public internet, put them on a private network or a WireGuard tunnel.</p>
63 +
64 +<h2>5. Tuning that matters for AMXX</h2>
65 +<p>An AMXX database is tiny and often shares the machine with HLDS, so most MySQL tuning advice does not apply. Put this in <code>/etc/mysql/mariadb.conf.d/60-amxx.cnf</code>:</p>
66 +<pre><code>[mysqld]
67 +skip-name-resolve
68 +innodb_buffer_pool_size = 128M
69 +slow_query_log = 1
70 +slow_query_log_file = /var/log/mysql/mariadb-slow.log
71 +long_query_time = 0.5</code></pre>
72 +<pre><code>sudo mkdir -p -m 2750 /var/log/mysql
73 +sudo chown mysql /var/log/mysql
74 +sudo systemctl restart mariadb</code></pre>
75 +<ul>
76 +<li><strong><code>skip-name-resolve</code></strong> stops MariaDB doing a reverse DNS lookup on every new connection. With slow DNS that lookup stalls the connect, and a plugin that connects without threading freezes the game while it waits. Grants by IP, as above, keep working.</li>
77 +<li><strong><code>innodb_buffer_pool_size</code></strong>: 128M holds an entire AMXX database many times over. Ignore guides that say 70 to 80 percent of RAM; that RAM belongs to HLDS here.</li>
78 +<li><strong>The slow query log</strong> names the plugin query that takes half a second, which is exactly the query that makes players stutter. Usually a missing index on a SteamID column.</li>
79 +</ul>
80 +<p>Also check the table engines. Old plugin SQL files sometimes create MyISAM tables, which lock the whole table on every write and are not covered by a consistent backup:</p>
81 +<pre><code>SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = &#039;amxx&#039;;
82 +ALTER TABLE some_table ENGINE=InnoDB;</code></pre>
83 +
84 +<h2>6. Backups with mariadb-dump and cron</h2>
85 +<p>Create <code>/usr/local/sbin/amxx-db-backup</code>:</p>
86 +<pre><code>#!/bin/bash
87 +set -euo pipefail
88 +DST=/var/backups/amxx
89 +mkdir -p -m 700 &quot;$DST&quot;
90 +mariadb-dump --single-transaction --routines --triggers amxx \
91 + | gzip &gt; &quot;$DST/amxx-$(date +%F_%H%M).sql.gz&quot;
92 +find &quot;$DST&quot; -name &#039;amxx-*.sql.gz&#039; -mtime +14 -delete</code></pre>
93 +<pre><code>sudo chmod 700 /usr/local/sbin/amxx-db-backup
94 +sudo crontab -e</code></pre>
95 +<pre><code>15 5 * * * /usr/local/sbin/amxx-db-backup</code></pre>
96 +<p>Running from root's crontab uses socket login, so no password is stored anywhere. <code>--single-transaction</code> takes a consistent snapshot of InnoDB tables without locking out the game server, and <code>pipefail</code> makes the job fail loudly if the dump fails instead of writing an empty archive. Keeping <code>date +%F</code> inside the script also dodges cron, which treats a bare <code>%</code> in a crontab line as a newline. Prove a backup restores before you need it. As root (<code>sudo -i</code>):</p>
97 +<pre><code>LATEST=$(ls -1t /var/backups/amxx/*.sql.gz | head -n 1)
98 +mariadb -e &quot;CREATE DATABASE amxx_restoretest&quot;
99 +zcat &quot;$LATEST&quot; | mariadb amxx_restoretest
100 +mariadb -e &quot;SHOW TABLES FROM amxx_restoretest&quot;
101 +mariadb -e &quot;DROP DATABASE amxx_restoretest&quot;</code></pre>
102 +<p>Copying the archives off the machine is covered in <a href="/tutorials/backup-configs-bans-stats">backing up configs, bans and stats</a>.</p>
103 +
104 +<h2>7. Verify from the game box</h2>
105 +<p>Test the path the plugin will use, from the game server, with the plugin's credentials:</p>
106 +<pre><code>sudo apt install -y mariadb-client
107 +mariadb -h 10.0.0.5 -u amxx -p amxx -e &quot;SELECT CURRENT_USER(); SHOW GRANTS;&quot;</code></pre>
108 +<p><code>CURRENT_USER()</code> should print <code>[email protected]</code>, followed by your <code>GRANT</code> line. If this works and the plugin still fails, the problem is in <code>sql.cfg</code>, not the database. A newer client talking to an older server may refuse with an SSL error; add <code>--skip-ssl</code> for this test, since the AMXX module does not use TLS anyway.</p>
109 +
110 +<h2>Common errors</h2>
111 +<ul>
112 +<li><strong><code>Access denied for user 'amxx'@'10.0.0.10' (using password: YES)</code></strong>: wrong password, or the user exists for a different host than the one in the message. The host in the message is the one to grant. See <a href="/tutorials/fix-mysql-access-denied-amxx">Access denied from an AMXX plugin</a>.</li>
113 +<li><strong><code>Host '10.0.0.10' is not allowed to connect to this MariaDB server</code></strong>: no user exists for that host at all. Create one for the IP shown.</li>
114 +<li><strong><code>Can't connect to MySQL server on '10.0.0.5' (111)</code></strong>: connection refused. MariaDB is still bound to <code>127.0.0.1</code>, not running, or a firewall rejects. See <a href="/tutorials/fix-mysql-cant-connect-111">errno 111</a>.</li>
115 +<li><strong>The connection hangs until it times out</strong>: a firewall is silently dropping 3306, often the cloud provider's firewall rather than the one on the box.</li>
116 +<li><strong>The game freezes for seconds when the database is remote</strong>: a plugin uses blocking queries, which a network round trip makes visible. See <a href="/tutorials/fix-server-freeze-mysql-query">server freezes on MySQL query</a>.</li>
117 +<li><strong>Backup files are a few bytes</strong>: the dump failed. Run the script by hand and read the error.</li>
118 +</ul>
119 +
120 +<h2>Verification checklist</h2>
121 +<ol>
122 +<li><code>ss -ltnp</code> shows 3306 on <code>127.0.0.1</code> (same host) or on the private IP (separate host), never unfiltered on <code>0.0.0.0</code>.</li>
123 +<li><code>SHOW GRANTS FOR</code> each <code>amxx</code> user lists only the <code>amxx</code> database and no <code>ALL PRIVILEGES</code>.</li>
124 +<li>From any IP other than the game server, port 3306 does not answer.</li>
125 +<li>The <code>mariadb</code> client test from the game box prints the expected <code>CURRENT_USER()</code>.</li>
126 +<li>A fresh <code>.sql.gz</code> appears each morning and restores into a test database.</li>
127 +</ol>
0 128