Public configuration files, scripts, and documentation for production servers.
All secrets, passwords, API keys and FULL IP addresses are stored in a separate PRIVATE repository.
Run these on any fresh server to get up and running fast.
bash <(curl -sL https://raw.githubusercontent.com/GinCz/Linux_Server_Public/main/scripts/new_server_install.sh)curl -fsSL https://raw.githubusercontent.com/GinCz/Linux_Server_Public/main/scripts/sos.sh \
-o /usr/local/bin/sos && chmod +x /usr/local/bin/sos && sosbash <(curl -sL https://raw.githubusercontent.com/GinCz/Linux_Server_Public/main/scripts/samba_setup.sh)bash <(curl -s https://raw.githubusercontent.com/GinCz/Linux_Server_Public/main/VPN/setup_aliases_and_motd.sh)These rules apply to every session. The AI must follow them without exception.
Before answering ANY question β the AI must:
- Read the root
README.md(this file) - Read the relevant server folder
README.md(e.g.222/README.mdorVPN/README.md) - Read
CHANGELOG.mdto understand recent changes - Read the actual script file before deciding what to do with it
- Only THEN answer, based on actual repo contents β not assumptions
If you are not sure what a script does β READ IT FIRST. Every time. No exceptions. Do NOT ask the server questions that can be answered by reading the repo.
Every change, no matter how small, must be saved to the repo. This includes:
- New scripts or config files
- Any changes to existing scripts
- New cron jobs or systemd units
- Every problem encountered and how it was solved
- Installation steps for any software
- Backup configurations
- Test results
If it was done on a server β it must exist in the repo. No exceptions.
| Where | Language | Notes |
|---|---|---|
| AI β VladiMIR (chat) | π·πΊ Russian only | Always communicate in Russian in chat |
This PUBLIC repo (Linux_Server_Public) |
π¬π§ English only | All .md files, all comments inside scripts, all descriptions |
Private repo (Secret_Privat) |
π·πΊ Russian | Descriptions, notes and comments in Russian |
Crypto bot repo (crypto-docker / private) |
π·πΊ Russian | Descriptions, notes and comments in Russian |
Summary:
- Chat with AI β always Russian
- Public GitHub repo β always English (code comments, README, all docs)
- Private / secret repos β Russian
When the AI sends code, it must always clearly mark one of these:
π INFO ONLY β do not run this
π RUN ON SERVER: xxx.xxx.xxx.222 (222-DE-NetCup)
π RUN ON SERVER: xxx.xxx.xxx.109 (109-RU-FastVDS)
π RUN ON SERVER: xxx.xxx.xxx.47 (VPN-EU-Alex-47)
π RUN ON ALL SERVERS
- Every executable code block must specify the exact server IP where it should run
- If multiple code blocks are needed for the same task β merge them into one script
- Every script must start with
clearto clear the terminal before output - Do NOT send 10 separate snippets when one combined script will do
| β Allowed in PUBLIC repo | β NEVER in PUBLIC repo |
|---|---|
Template placeholders <VALUE> |
Real passwords |
IP format: xxx.xxx.xxx.222 |
Full IP addresses |
| Script logic and structure | API keys / tokens |
| Config templates | SSH private keys |
| Documentation | WireGuard private keys |
| Masked IPs (last octet only visible) | Telegram Bot tokens |
| SSH public keys (even public keys reveal infrastructure) |
IP masking format: only the last octet is shown. Examples:
152.53.182.222βxxx.xxx.xxx.222212.109.223.109βxxx.xxx.xxx.109109.234.38.47βxxx.xxx.xxx.47
Full IPs, passwords and keys β stored ONLY in the private Secret_Privat repository.
All configuration must be done at the SERVER level β never per-account or per-domain.
- PHP settings (
memory_limit,max_execution_time,opcache, etc.) β set globally inphp.iniorwww.conf - Nginx settings (timeouts, buffers, limits) β set globally in
nginx.conforconf.d/ - MariaDB settings β set globally in
my.cnf - CrowdSec rules β applied globally to all sites automatically
- PHP-FPM pool parameters β use a global template applied to all pools equally
- Individual per-site tuning creates inconsistency and technical debt
- If one site needs more resources, the server needs upgrading β not that one site's config
- All hosted sites are equal β no site gets special treatment at config level
- Easier maintenance: one change fixes all sites at once
If a site shows errors, high CPU, memory issues, or behaves differently from others β do NOT edit its config files directly. Instead:
- Check if WordPress is up to date β log into the site's WP Admin and update all plugins, themes, and WordPress core
- Check if a CAPTCHA plugin is installed and working β every WP site must have an active, up-to-date CAPTCHA (e.g. Cloudflare Turnstile, hCaptcha, or similar)
- Check for outdated or abandoned plugins β deactivate anything not updated in 12+ months
- If the problem persists β investigate at the server level (PHP-FPM pool stats, error logs, CrowdSec decisions)
The AI must notify VladiMIR when a specific domain behaves differently from others:
"Domainexample.czis generating errors β please log into WP Admin, update all plugins/themes/core, and verify that a CAPTCHA plugin is installed and active."
This rule was added on 2026-06-03 at VladiMIR's direct request.
The AI must always evaluate both sides of any proposal before responding β not just confirm what VladiMIR suggests.
- Every idea, script approach, or architectural decision must be assessed for both advantages AND risks
- If VladiMIR's proposal has a real downside β say so clearly, even if it means disagreeing
- Do NOT give answers designed to please β give answers that are technically correct
- Flattery and blind agreement are forbidden. They waste time and cause real problems on production servers.
β Wrong (AI just agrees):
VladiMIR: "Let's apply this rule to ALL domains in the account automatically." AI: "Great idea! I'll implement it right away."
β Correct (AI evaluates both sides):
VladiMIR: "Let's apply this rule to ALL domains in the account automatically." AI: "Advantage: no need to maintain a domain list, new domains are covered automatically. Risk: if the account contains non-WordPress domains (landing pages, redirect-only zones, API endpoints), applying WordPress-specific WAF rules to them could block legitimate traffic or break functionality. Recommendation: add a domain-type flag or exclusion list if mixed domain types exist. In your case, all domains appear to be WordPress β so this approach is justified."
A good engineer challenges bad ideas before they reach production. An AI that only agrees is useless.
This rule was added on 2026-06-09. The AI must NEVER manually ban or unban IPs that belong to the whitelist below.
The blacklist system is 100% automatic β no manual intervention is ever needed for normal operation.
| Component | Location | What it does |
|---|---|---|
| CrowdSec | All servers | Auto-detects attacks, auto-bans IPs via bouncer |
| iptables + ipset | All servers | Hardware-level DROP for vladblacklist IPs |
vladblacklist ipset |
All servers | ~157 IPs/subnets, auto-deployed every 3h via cron |
blacklist/collect-blacklist.sh |
222 server | Collects new bad IPs every 3h |
blacklist/deploy-blacklist.sh |
All servers | Pulls and applies the list every 3h |
blacklist/collect-from-vpn.sh |
222 server | Collects IPs from VPN nodes every 3h |
Cron schedule (on 222):
0 */3 * * * collect-blacklist.sh β collect new bad IPs
30 */3 * * * deploy-blacklist.sh β push to all servers
55 */3 * * * collect-from-vpn.sh β gather VPN node data
The following IPs belong to the infrastructure and must always be whitelisted in CrowdSec, iptables, Fail2ban, and Samba on ALL servers.
Before banning any IP β check this table first.
When installing CrowdSec or configuring any firewall β add all these IPs to the whitelist.
| IP Address | Name / Role | Services |
|---|---|---|
xxx.xxx.xxx.222 |
222-DE-NetCup (main web server) | FastPanel + Cloudflare + Samba + XRAY VPN + CryptoBot |
xxx.xxx.xxx.109 |
109-RU-FastVDS (Russian sites server) | FastPanel + Samba + XRAY VPN |
xxx.xxx.xxx.47 |
VPN ALEX_47 | XRAY VPN + Samba |
xxx.xxx.xxx.237 |
VPN 4TON_237 | XRAY VPN + Samba |
xxx.xxx.xxx.9 |
VPN TATRA_9 | XRAY VPN + Samba + Monitoring Kuma |
xxx.xxx.xxx.227 |
VPN SHAHIN_227 | AmneziaWG + Samba |
xxx.xxx.xxx.24 |
VPN STOLB_24 | XRAY VPN + Samba + AdGuard Home |
xxx.xxx.xxx.178 |
VPN PILIK_178 | AmneziaWG + Samba |
xxx.xxx.xxx.176 |
VPN ILYA_176 | AmneziaWG + Samba |
xxx.xxx.xxx.38 |
VPN SO_38 | XRAY VPN + Samba |
xxx.xxx.xxx.38 |
IONOS-38 (IONOS server β different IP, same last octet as SO_38) | IONOS server |
xxx.xxx.xxx.42 |
AWS-VPN (AWS server) | AWS VPN XRAY |
xxx.xxx.xxx.16 |
Home IP (primary) | Admin access |
xxx.xxx.xxx.235 |
Home IP (secondary) | Admin access |
xxx.xxx.xxx.0 |
Home IP (tertiary) | Admin access |
xxx.xxx.xxx.10 |
Work IP | Admin access |
β οΈ Note: BothVPN SO_38andIONOS-38end in.38but are completely different IPs from different providers. Full IPs inSecret_Privatrepo only.
# Add all infrastructure IPs to CrowdSec whitelist
cscli decisions delete --ip xxx.xxx.xxx.222 2>/dev/null
cscli decisions delete --ip xxx.xxx.xxx.109 2>/dev/null
# Permanent whitelist β edit /etc/crowdsec/parsers/s02-enrich/my_whitelist.yamlWhitelist config file: /etc/crowdsec/parsers/s02-enrich/my_whitelist.yaml
name: my_whitelist
description: "Trusted IPs - servers, VPN clients, admin. v2026-06-10"
whitelist:
reason: "Trusted admin, VPN clients, monitoring and partner servers"
ip:
# --- OWN SERVERS ---
- "xxx.xxx.xxx.222" # DE-NetCup 222 (WEB+VPN+CryptoBot)
- "xxx.xxx.xxx.109" # RU-FastVDS 109 (WEB+VPN)
- "xxx.xxx.xxx.38" # IONOS-38 (our server β different IP from SO_38)
- "xxx.xxx.xxx.42" # AWS VPN XRAY
# --- VPN NODES ---
- "xxx.xxx.xxx.47" # ALEX_47
- "xxx.xxx.xxx.237" # 4TON_237
- "xxx.xxx.xxx.9" # TATRA_9 (Kuma Monitoring)
- "xxx.xxx.xxx.227" # SHAHIN_227
- "xxx.xxx.xxx.24" # STOLB_24 (AdGuard Home)
- "xxx.xxx.xxx.178" # PILIK_178
- "xxx.xxx.xxx.176" # ILYA_176
- "xxx.xxx.xxx.38" # SO_38 (different IP from IONOS-38)
# --- HOME / WORK ---
- "xxx.xxx.xxx.16" # Home IP VladiMIR
- "xxx.xxx.xxx.235" # Home IP VladiMIR 2
- "xxx.xxx.xxx.0" # Home IP VladiMIR 3
- "xxx.xxx.xxx.10" # Work IP VladiMIR- NEVER suggest banning any IP from the whitelist above
- BEFORE writing any firewall command β check if the target IP is in this table
- When setting up a new server β always add all whitelist IPs to CrowdSec, iptables, and Samba before anything else
- The blacklist system runs automatically β do not interfere with its cron jobs
This section was written after a painful 1-hour session on May 22, 2026.
Every mistake described here actually happened. Read carefully β do NOT repeat.
VladiMIR asked: "There's a script β maybe it's a VPN installer, maybe it's aliases setup. Read it and tell me what it does before I run it on a production server with active Xray VPN users."
What the AI did wrong β step by step:
-
Did NOT read the script first. Jumped to conclusions based on the filename alone. This is the core mistake. The AI assumed instead of reading.
-
Wrote new code without being asked. VladiMIR asked "what does this script do?" β the AI started writing a new installer. Nobody asked for that.
-
Confused two completely different scripts:
motd_vpn.shβ this IS the MOTD banner script. It runs on SSH login and displays the banner. It does NOT install anything.setup_aliases_and_motd.shβ this IS the installer. It copies files, installs packages, configures system.- The AI kept swapping them, offering the wrong one each time.
-
Broke a working server by uploading a new script to the repo without confirmation, and that script overwrote the correct MOTD with a "Modded" version that VladiMIR did not want.
-
Sent multiple separate code blocks instead of one clean command. VladiMIR's rule is: one task = one
clear-prefixed command. -
Did not stop and ask the ONE key question that would have resolved everything in 30 seconds: "Which file exactly are you asking about β show me the path or name."
VladiMIR: "There's a script, I think it sets up VPN. Read it before I run it."
AI step 1: Read README.md β understand the repo structure
AI step 2: Read VPN/README.md β understand VPN node architecture
AI step 3: Read the actual script file (motd_vpn.sh or setup_aliases_and_motd.sh)
AI step 4: Report what it does IN PLAIN LANGUAGE
AI step 5: Say "this is safe / NOT safe to run on a production server"
AI step 6: If installation needed β one clean command starting with clear
Total time if done correctly: 2 minutes.
Actual time because of mistakes: 1 hour.
User mentions a script β AI reads it β AI reports what it does β AI asks "should I run it?"
NEVER: User mentions a script β AI writes new code
Server xxx.xxx.xxx.47 (EU-Alex-47) has active Xray VPN users connected 24/7.
Server xxx.xxx.xxx.237 (EU-4Ton-237) has active Xray VPN users connected 24/7.
Any mistake that restarts Xray, UFW, or the server = users lose their VPN = real problem.
Before running ANYTHING on a VPN node, the AI must verify:
- Does this command restart Xray? β warn VladiMIR first
- Does this command restart UFW / networking? β warn VladiMIR first
- Does this command reboot the server? β STOP, ask for explicit confirmation
- Does this command upgrade packages (
apt upgrade)? β warn, do not run silently
| File | What it IS | What it DOES | Safe on production? |
|---|---|---|---|
VPN/motd_vpn.sh |
The banner itself | Displays MOTD on SSH login | β Read-only, safe |
VPN/motd_server.sh |
The banner itself | Same β newer universal version | β Read-only, safe |
VPN/setup_aliases_and_motd.sh |
The installer | Copies files, configures system | |
scripts/new_server_install.sh |
Full bootstrap | apt upgrade, UFW, CrowdSec, etc. | β ONLY on fresh servers |
The banner file (motd_vpn.sh / motd_server.sh) just runs and prints text. It is NOT an installer.
To deploy the banner, it must be copied to /etc/profile.d/ β that is the install step.
Correct one-liner to deploy MOTD on a VPN node:
π RUN ON SERVER: xxx.xxx.xxx.47 (VPN-EU-Alex-47)
clear
cd /root/Linux_Server_Public && git pull origin main --no-rebase --no-edit \
&& rm -f /etc/profile.d/motd_banner.sh /etc/profile.d/motd_custom.sh \
&& cp VPN/motd_vpn.sh /etc/profile.d/motd_vpn.sh \
&& chmod +x /etc/profile.d/motd_vpn.sh \
&& chmod -x /etc/update-motd.d/* 2>/dev/null \
&& echo "Done. Re-login to verify."- Every answer that requires running something on a server = exactly one code block
- That block starts with
clear - That block is labeled with the exact server IP
- No "first run this, then run that" β merge into one
If the AI doesn't know which script, which server, which version, or what the goal is:
β Ask one specific question
β Wait for the answer
β Then act
Do NOT guess. Do NOT write code based on assumptions.
Every script committed to this repository must follow these rules:
These are the ONLY three colours used in ALL scripts. No other colours allowed.
CYN='\033[1;36m' # Bright Cyan β section headers, info blocks, labels
GRN='\033[1;32m' # Bright Green β success messages, OK status, borders/dividers
YEL='\033[1;33m' # Bright Yellow β warnings, detected values, highlights
NC='\033[0m' # Reset colour β always used after every coloured echo
β οΈ Important: Use\033[1;XX m(bold/bright variants), NOT\033[0;XXm(dark variants).
\033[1;32m= Bright Green β β correct\033[0;32m= Dark Green β β do NOT use\033[1;36m= Bright Cyan β β correct\033[0;36m= Dark Cyan β β do NOT use
Colour usage rules:
GRNβ success lines, "OK" messages, horizontal divider lines in headersYELβ warnings, detected config values, items that need attentionCYNβ section headings, info labels, structural text
No RED for errors. If something is wrong, use YEL with a
RED is not part of this colour scheme and must not appear in any script output.
Every script must start with a bright green horizontal border of exactly 90 = characters, followed by the header block, followed by another 90-character border. Only horizontal lines β no vertical bars or side borders.
#!/bin/bash
clear
# ==========================================================================================
# Script: script_name.sh
# Version: v2026-MM-DD
# Location: folder/script_name.sh
# Server: [e.g. ALL | 222-DE-NetCup xxx.xxx.xxx.222 | VPN nodes]
# Alias: [alias name if defined, e.g. "save" | "none"]
# Run from repo (curl one-liner):
# bash <(curl -sL https://raw.githubusercontent.com/GinCz/Linux_Server_Public/main/folder/script_name.sh)
# Description: What this script does (2-4 sentences).
# Dependencies: [tools required, e.g. docker, pigz, curl | none]
# WARNING: [side effects if any, e.g. restarts nginx | none]
# = Rooted by VladiMIR + AI | vYYYY.MM.DD | github.com/GinCz =
# ==========================================================================================The printed (runtime) header that appears in the terminal uses colour and must look like this:
GRN='\033[1;32m'
CYN='\033[1;36m'
YEL='\033[1;33m'
NC='\033[0m'
echo -e "${GRN}==========================================================================================${NC}"
echo -e "${CYN} Script Name β short description v2026-MM-DD${NC}"
echo -e "${GRN}==========================================================================================${NC}"Rules:
- The
==border line must be exactly 90 characters wide - Border lines are
GRN(Bright Green) β horizontal only, no vertical characters - The title line between borders is
CYN(Bright Cyan) clearmust be the first executable line (after#!/bin/bash)- The
curlone-liner in the comment header allows running the script on any server without cloning the repo Location:shows the path relative to repo rootAlias:shows the bash alias that runs this script (if any), ornoneServer:shows where this script is intended to run- The signature line
= Rooted by VladiMIR + AI | vYYYY.MM.DD | github.com/GinCz =must match the script version date
# Version: v2026-MM-DD
β οΈ The version must NEVER appear in the filename.
Correct:backup_clean.sh
Wrong:backup_clean_v2026-04-28.shVersion history is tracked by Git β every commit has a date, author and SHA.
To recover an older version:git log -- 222/backup_clean.shthengit show <sha>:222/backup_clean.sh
- β
Templates with
<PLACEHOLDER>β allowed - β
Masked IPs
xxx.xxx.xxx.222β allowed - β Passwords, API keys, tokens, private keys β NEVER in this repo
- β Full IP addresses β NEVER in this repo
- β SSH public keys β NEVER in this repo (reveals infrastructure)
- Real credentials and IPs β private
Secret_Privatrepo only
| Location | Purpose |
|---|---|
222/ |
Scripts/configs for NetCup Germany server |
109/ |
Scripts/configs for FastVDS Russia server |
VPN/ |
Scripts/configs for X-ray / x-ui VPN nodes (AmneziaWG + Xray) |
XRAY/ |
x-ui / Xray installer scripts |
scripts/ |
Shared across ALL servers (including sos.sh, infooo.sh) |
Rule: filename = clean name only. Version inside the script, not in the filename.
description.sh
Examples:
- β
backup_clean.shβ correct - β
setup_aliases_and_motd.shβ correct - β
sos.shβ correct - β
backup_clean_v2026-04-28.shβ wrong, version in filename - β
setup_aliases_and_motd_vpn_v2026-04-25.shβ wrong
Numbered utility scripts (legacy exception):
NN_servername_description.sh
Example: 01_222_clean_vpn_reports.sh
LinuxServerPublic/
βββ 222/ β Server 222-DE-NetCup (xxx.xxx.xxx.222) β NetCup.com, Germany
β Ubuntu 24 / FASTPANEL / Cloudflare / CZ+EU sites
β 4 vCore AMD EPYC-Genoa / 8 GB DDR5 ECC / 256 GB NVMe
β Tariff: VPS 1000 G12 (2026) β 8.60 β¬/mo
β Key files: setup_aliases_and_motd.sh, SSH-Cursor-Setup.md
β π Full docs: 222/README.md
β
βββ 109/ β Server 109-RU-FastVDS (xxx.xxx.xxx.109) β FastVDS.ru, Russia
β Ubuntu 24 / FASTPANEL / No Cloudflare / RU sites
β 4 vCore AMD EPYC 7763 / 8 GB RAM / 80 GB NVMe
β Tariff: VDS-KVM-NVMe-Otriv-10.0 β 13 β¬/mo
β Key files: setup_aliases_and_motd.sh
β π Full docs: 109/README.md
β
βββ VPN/ β VPN infrastructure (x-ui / Xray VLESS+Reality + AmneziaWG)
β 8 VPN nodes β all running Xray 26.5.9
β SHAHIN_227 + PILIK_178: AmneziaWG via Docker (active) + Xray
β Automated backup system: x-ui archives
β Key files: motd_vpn.sh (banner), setup_aliases_and_motd.sh (installer)
β π Full docs: VPN/README.md
β
βββ XRAY/ β x-ui / Xray installer scripts
β Safe / Clean / Full-clean installers
β
βββ scripts/ β Shared scripts used by ALL servers
β sos.sh β universal server health monitor (ALL servers)
β shared_aliases.sh β common aliases (save, load, aw, mc...)
β new_server_install.sh β full bootstrap for fresh servers ONLY
β samba_setup.sh β Samba installer for any server
β apply_aliases.sh β universal aliases+MOTD+MC setup (all server types)
β infooo.sh β legacy server info script
β
βββ CHANGELOG.md β Full history of all changes
βββ OPERATIONS.md β Operational procedures and runbooks
βββ domains.md β Domain list and DNS configuration
βββ README.md β This file β AI rules, standards, quick reference
| Name | IP (masked) | Provider | Location | Panel | Cloudflare | Monthly |
|---|---|---|---|---|---|---|
| 222-DE-NetCup | xxx.xxx.xxx.222 | NetCup.com | Germany | FASTPANEL | β Yes | 8.60 β¬ |
| 109-RU-FastVDS | xxx.xxx.xxx.109 | FastVDS.ru | Russia | FASTPANEL | β No | 13 β¬ |
| IONOS-38 | xxx.xxx.xxx.38 | IONOS | β | β | β No | β |
| AWS-VPN | xxx.xxx.xxx.42 | AWS | β | β | β No | β |
Hardware (222 + 109): 4 vCore AMD EPYC / 8 GB RAM / 80β256 GB NVMe / Ubuntu 24 LTS
All 8 nodes are running x-ui / Xray v26.5.9 (VLESS + Reality protocol).
SHAHIN_227 and PILIK_178 additionally run AmneziaWG via Docker (active, UDP ports).
| Node Name | IP (masked) | Xray | Xray Port | AmneziaWG | AWG UDP Port | Extra Services | Active Users |
|---|---|---|---|---|---|---|---|
| ALEX_47 | xxx.xxx.xxx.47 | β 26.5.9 | 443 | β | β | Samba | |
| 4TON_237 | xxx.xxx.xxx.237 | β 26.5.9 | 443 | β | β | Samba, Prometheus | |
| TATRA_9 | xxx.xxx.xxx.9 | β 26.5.9 | 443 | β | β | Samba, Uptime Kuma | |
| SHAHIN_227 | xxx.xxx.xxx.227 | β 26.5.9 | 2096 | β Docker | 35628 | Samba, Prometheus | |
| STOLB_24 | xxx.xxx.xxx.24 | β 26.5.9 | 8443 | β | β | Samba, AdGuard Home | |
| PILIK_178 | xxx.xxx.xxx.178 | β 26.5.9 | 2096 | β Docker | 39339 | Samba, Prometheus | |
| ILYA_176 | xxx.xxx.xxx.176 | β 26.5.9 | 443 | β | β | Samba | |
| SO_38 | xxx.xxx.xxx.38 | β 26.5.9 | 443 | β | β | Samba |
β All 8 nodes: x-ui / Xray v26.5.9 β VLESS + Reality protocol
β SHAHIN_227: AmneziaWG Docker containeramnezia-awgβ Up, UDP :35628 β confirmed active (2026-05-31)
β PILIK_178: AmneziaWG Docker containeramnezia-awgβ Up, UDP :39339 β confirmed active (2026-05-31)
β οΈ SHAHIN_227 + PILIK_178:amneziawgbinary not in PATH inside container β this is normal foramneziavpn/amnezia-wgimage (VPN works via kernel module, not CLI binary)
β οΈ STOLB_24: port 8443 because AdGuard Home occupies port 443
β οΈ ALL VPN nodes have real users connected β NEVER restart Xray/UFW/networking without warning
Full IPs, keys and configs β privateSecret_Privatrepository only.
| Item | Value |
|---|---|
| Docker image | amneziavpn/amnezia-wg:latest (21.2 MB) |
| Container name | amnezia-awg |
| Status | Up 44+ hours (confirmed 2026-05-31) |
| SHAHIN UDP port | 35628 |
| PILIK UDP port | 39339 |
amneziawg in PATH |
β Not found β this is normal, the image does not expose this binary |
| How to check status | docker ps + ss -ulnp | grep docker-proxy |
| How to check AWG peers | docker exec amnezia-awg wg show |
Understanding which file does what PREVENTS running the wrong script on a live server.
| File | Type | What it does | Safe to run on live server? |
|---|---|---|---|
VPN/motd_vpn.sh |
Banner script | Prints the SSH welcome banner β that's it | β Safe, read-only |
VPN/motd_server.sh |
Banner script | Same, newer universal version | β Safe, read-only |
VPN/.bashrc |
Shell config | Defines aliases for the VPN node | β Safe to copy |
VPN/setup_aliases_and_motd.sh |
Installer | Copies .bashrc + MOTD to system paths | |
scripts/new_server_install.sh |
Full bootstrap | apt upgrade + UFW + CrowdSec + everything | β ONLY fresh servers |
VPN/crowdsec_install_vpn.sh |
CrowdSec installer | Installs CrowdSec from scratch | |
VPN/vpn_hard_shield.sh |
Firewall hardening | Rewrites ALL iptables rules | β NEVER on live VPN node |
SSH login to VPN node
βββ Linux runs: /etc/profile.d/*.sh (all files in alphabetical order)
βββ /etc/profile.d/motd_vpn.sh β this IS the banner
βββ detects Xray status
βββ detects AmneziaWG (Docker)
βββ detects CrowdSec + ban count
βββ shows RAM / CPU / uptime
βββ prints the alias menu
The banner is NOT installed automatically. To deploy it, copy it to /etc/profile.d/:
cp /root/Linux_Server_Public/VPN/motd_vpn.sh /etc/profile.d/motd_vpn.sh
chmod +x /etc/profile.d/motd_vpn.shSSH login
βββ Bash loads: /root/.bashrc
βββ This file is copied from: VPN/.bashrc
βββ Defines: xray_st, xray_log, sos, sos24, banlist, save, load, 00, etc.
To deploy/update aliases on a VPN node:
cp /root/Linux_Server_Public/VPN/.bashrc /root/.bashrc
source /root/.bashrcπ RUN ON SERVER: xxx.xxx.xxx.47 (VPN-EU-Alex-47)
clear
cd /root/Linux_Server_Public && git pull origin main --no-rebase --no-edit \
&& cp VPN/.bashrc /root/.bashrc \
&& source /root/.bashrc \
&& cp VPN/motd_vpn.sh /etc/profile.d/motd_vpn.sh \
&& chmod +x /etc/profile.d/motd_vpn.sh \
&& echo "Done β re-login to verify banner"This command:
- β Pulls latest from repo
- β Updates aliases
- β Updates MOTD banner
- β Does NOT touch Xray, UFW, CrowdSec, or any service
- β Does NOT restart anything
- β Safe on a live server with active users
Understanding this prevents the double MOTD display bug.
When you SSH into a server, Linux runs two separate chains:
SSH login
βββ 1. LOGIN SHELL chain: /etc/profile β /etc/profile.d/*.sh
β βββ /etc/profile.d/motd_server.sh β MOTD shown here (1st)
β
βββ 2. INTERACTIVE BASH: /root/.bashrc
βββ source /root/Linux_Server_Public/222/.bashrc
βββ source scripts/shared_aliases.sh
If motd_server.sh has no guard, it fires on both chains β MOTD shown twice.
All motd_server.sh files now have a 2-line guard at the top:
shopt -q login_shell || return 0 2>/dev/null || exit 0
[ -n "$SSH_CONNECTION" ] || return 0 2>/dev/null || exit 0shopt -q login_shellβ true only for a login shell (SSH), false forsource .bashrc$SSH_CONNECTIONβ set only for real remote SSH sessions, empty for local/cron
Result: MOTD fires exactly once β on SSH login only.
/root/.bashrc
βββ source /root/Linux_Server_Public/222/.bashrc β server-specific aliases
βββ source /root/Linux_Server_Public/scripts/shared_aliases.sh β shared aliases
| File | Purpose | On server | In repo |
|---|---|---|---|
/root/.bashrc |
Entry point, loads repo .bashrc | /root/.bashrc |
222/.bashrc |
222/.bashrc |
Server-specific aliases + PS1 | sourced by above | 222/.bashrc |
scripts/shared_aliases.sh |
Aliases shared by ALL servers | sourced by 222/.bashrc | scripts/shared_aliases.sh |
/etc/profile.d/motd_server.sh |
MOTD banner (login only) | auto-run at SSH login | 222/motd_server.sh |
Because load must source /root/Linux_Server_Public/222/.bashrc β the path is server-specific.
If load were in shared_aliases.sh, it would be wrong on every other server.
The script setup_aliases_and_motd.sh exists in three versions, one per environment:
| File | Server | Deploys |
|---|---|---|
222/setup_aliases_and_motd.sh |
222-DE-NetCup | MOTD + aliases + MC F2 menu for 222 |
109/setup_aliases_and_motd.sh |
109-RU-FastVDS | MOTD + aliases + MC F2 menu for 109 |
VPN/setup_aliases_and_motd.sh |
VPN nodes | MOTD + aliases + MC F2 menu for VPN |
Note: Version is stored inside the script only (
# Version: vYYYY-MM-DD).
The filename never contains a version β onlysetup_aliases_and_motd.sh.
β οΈ This section was written after 2 full days of debugging. Read carefully β do NOT repeat this.
mc checks these locations in order and uses the FIRST one it finds:
| Priority | Path | Notes |
|---|---|---|
| 1st |
~/.mc.menu |
Hidden file in /root/ β THIS IS THE TRAP |
| 2nd | ~/.config/mc/menu |
Correct user menu location |
| 3rd | ~/.config/mc/mc.menu |
Also checked β causes confusion if both exist |
| 4th | /etc/mc/mc.menu |
System-wide fallback |
Problem: F2 showed a broken menu with contents like:
panel.1.directory=/root/Linux_Server_Public/222
panel.1.left
panel.2.directory=/root/Linux_Server_Public/scripts
user_menu=1
Root cause: File /root/.mc.menu existed (233 bytes, created Mar 24).
This is an old ini-style config fragment that mc was reading as the User Menu.
mc always checks ~/.mc.menu FIRST β before ~/.config/mc/menu.
Fix:
# Check if the trap file exists
ls -la /root/.mc.menu
# Delete it
rm /root/.mc.menu
# Verify correct menu is in place
head -3 ~/.config/mc/menuThe correct menu file must be at ~/.config/mc/menu:
# Deploy correct menu from repo (222 server)
cp /root/Linux_Server_Public/222/mc.menu ~/.config/mc/menu
chmod 644 ~/.config/mc/menu
# Verify
head -5 ~/.config/mc/menu
# Should start with: # mc.menu for 222-DE-NetCupFile: ~/.config/mc/ini
auto_save_setup=false β MUST be false β if true, mc overwrites menu on exit
auto_menu=false β MUST be false β if true, mc opens menu automatically on startCheck and fix:
grep "auto_save_setup\|auto_menu" ~/.config/mc/ini
sed -i 's/auto_save_setup=true/auto_save_setup=false/' ~/.config/mc/ini| Server | Repo source | Deploy target |
|---|---|---|
| 222-DE-NetCup | 222/mc.menu |
~/.config/mc/menu |
| 109-RU-FastVDS | 109/mc.menu |
~/.config/mc/menu |
π RUN ON SERVER where F2 is broken
clear
echo "=== TRAP FILE ===" && ls -la /root/.mc.menu 2>/dev/null || echo "OK β not present"
echo "=== CORRECT MENU ===" && head -3 ~/.config/mc/menu 2>/dev/null || echo "MISSING"
echo "=== ALL mc menu files ===" && find / -name "menu" -path "*/mc/*" 2>/dev/null
echo "=== INI auto_save ===" && grep "auto_save_setup\|auto_menu" ~/.config/mc/ini
echo "=== ALIAS mc ===" && alias | grep "alias mc"
echo "=== DONE ==="Expected output:
=== TRAP FILE ===
OK β not present
=== CORRECT MENU ===
# mc.menu for 222-DE-NetCup β auto-generated by server_222.sh --install
π RUN ON SERVER: xxx.xxx.xxx.222 (222-DE-NetCup)
clear
rm -f /root/.mc.menu
cp /root/Linux_Server_Public/222/mc.menu ~/.config/mc/menu
chmod 644 ~/.config/mc/menu
sed -i 's/auto_save_setup=true/auto_save_setup=false/' ~/.config/mc/ini
echo "=== MC F2 menu fixed ===" && head -3 ~/.config/mc/menuπ RUN ON SERVER: xxx.xxx.xxx.109 (109-RU-FastVDS)
clear
rm -f /root/.mc.menu
cp /root/Linux_Server_Public/109/mc.menu ~/.config/mc/menu
chmod 644 ~/.config/mc/menu
sed -i 's/auto_save_setup=true/auto_save_setup=false/' ~/.config/mc/ini
echo "=== MC F2 menu fixed ===" && head -3 ~/.config/mc/menuMOTD = the banner you see every time you SSH into the server.
| Server | File on server | File in repo |
|---|---|---|
| 222-DE-NetCup | /etc/profile.d/motd_server.sh |
222/motd_server.sh |
| 109-RU-FastVDS | /etc/profile.d/motd_server.sh |
109/motd_server.sh |
| VPN nodes | /etc/profile.d/motd_vpn.sh |
VPN/motd_vpn.sh |
π RUN ON SERVER: xxx.xxx.xxx.222 (222-DE-NetCup)
clear
nano /etc/profile.d/motd_server.sh
# Find the block: # Row 1 (SCAN/SERVER/WORDPRESS) or # Row 2 (BOT/GIT/TOOLS)
# Each line format:
# echo -e " ${G}aliasname${X}(description) ${G}alias2${X}(desc)"
# Column width: ~26 chars per column (use spaces to align)
# Test immediately:
bash /etc/profile.d/motd_server.sh
# Save to repo:
cd /root/Linux_Server_Public
cp /etc/profile.d/motd_server.sh 222/motd_server.sh
save| Server | File on server | File in repo |
|---|---|---|
| 222-DE-NetCup | /root/.bashrc |
222/.bashrc |
| 109-RU-FastVDS | /root/.bashrc |
109/.bashrc |
| VPN nodes | /root/.bashrc |
VPN/.bashrc |
| ALL servers (shared) | sourced from .bashrc |
scripts/shared_aliases.sh |
π RUN ON SERVER: xxx.xxx.xxx.222 (222-DE-NetCup)
clear
nano /root/.bashrc
# Add line: alias myalias='command'
source /root/.bashrc # apply without re-login
# Also add it to MOTD menu (motd_server.sh) so it shows in the banner!
# Save to repo:
cd /root/Linux_Server_Public
cp /root/.bashrc 222/.bashrc
saveπ RUN ON SERVER: xxx.xxx.xxx.222 (222-DE-NetCup)
clear
# Pull latest from repo and install on server:
cd /root/Linux_Server_Public && git pull
cp 222/motd_server.sh /etc/profile.d/motd_server.sh
cp 222/.bashrc /root/.bashrc
source /root/.bashrc
bash /etc/profile.d/motd_server.sh
# After editing files on server β push back to repo:
cd /root/Linux_Server_Public
cp /etc/profile.d/motd_server.sh 222/motd_server.sh
cp /root/.bashrc 222/.bashrc
saveπ INFO ONLY β run on your LOCAL machine
ssh-keygen -t ed25519 -C "yourname@server" -f ~/.ssh/id_ed25519_servernameπ INFO ONLY β adjust IP before running
ssh-copy-id -i ~/.ssh/id_ed25519_servername.pub root@SERVER_IP
# OR manually:
cat ~/.ssh/id_ed25519_servername.pub >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keysSee full setup guide: 222/SSH-Cursor-Setup.md
Host netcup
HostName <FULL_IP_FROM_SECRET_REPO>
User root
Port 2222
IdentityFile C:\\Users\\USER\\.ssh\\id_ed25519_win
Host fastvds alex47 4ton237 tatra9 shahin227 stolb24 pilik178 ilya176 so38
User root
Port 22
IdentityFile C:\\Users\\USER\\.ssh\\id_ed25519_win
ProxyJump netcup
π RUN ON SERVER where CrowdSec is broken
clear
mkdir -p /etc/crowdsec/hub
cscli hub update
cscli hub upgrade
systemctl restart crowdsec
systemctl status crowdsec --no-pager | head -5If you receive a Telegram alert:
β οΈ 222-DE-NetCup
PHP-FPM pool kk-med.eu
CPU=103% for 29min β php-fpm restarted automatically
This means the watchdog (php_fpm_watchdog.sh) detected a runaway PHP-FPM pool and restarted it.
This is normal auto-recovery β no manual action needed unless it repeats.
To investigate:
π RUN ON SERVER: xxx.xxx.xxx.222 (222-DE-NetCup)
clear
watchdog # check current PHP-FPM state
sos # check recent nginx/php errors
wphealth # check WordPress sites health- Script:
scripts/backup_all_servers_v2026-04-28.sh - Alias:
f5backup - What: Backs up ALL 10 servers in one run:
- Configs: nginx, php, mysql, crowdsec, fail2ban, ufw, cron, systemd, bashrc, ssh keys
- Docker image archives for: crypto-bot, semaphore (222), amnezia-awg2 (109)
- x-ui / Xray dirs for: ALEX, 4TON, TATRA, STOLB, SO, SHAHIN, PILIK, ILYA nodes
- Schedule: Wednesday 03:00 + Saturday 03:00 via cron on 222
- Keeps: last 10 date-folders per server (~5 weeks)
- Storage:
/BACKUP/<SERVER_LABEL>/<YYYY-MM-DD>/ - Telegram: sends summary after completion
- Script:
VPN/xray_backup_all_nodes.sh - Alias:
f5xray - What: Archives
/usr/local/x-ui,/etc/x-ui,/usr/local/share/xray,/root/cert,/etc/xrayfrom each node - Nodes backed up: ALL 8 VPN nodes
- Schedule: Sunday 03:00 via cron
- Keeps: last 8 archives per node (~2 months history)
- Storage:
/BACKUP/vpn/<NODE>/xray/ - Archive size: ~47 MB per node
- Script:
222/backup_clean.shand109/backup_clean.sh - Backs up all WordPress sites, databases, and configs
- Full docs:
222/README.md
π RUN ON SERVER: xxx.xxx.xxx.222 (222-DE-NetCup)
clear
bash /root/Linux_Server_Public/222/set_php_fpm_limits.shπ RUN ON SERVER: xxx.xxx.xxx.109 (109-RU-FastVDS)
clear
bash /root/Linux_Server_Public/109/set_php_fpm_limits.sh| Parameter | Value | Effect |
|---|---|---|
pm.max_children |
β€8 (calc from RAM) | Limits concurrent PHP processes |
pm.max_requests |
500 | Prevents memory leaks |
CPUQuota |
320% (4 cores Γ 80%) | Hard CPU cap via systemd |
MemoryMax |
~6.8 GB (85% of 8 GB) | Hard RAM cap via systemd |
OOMScoreAdjust |
300 | OOM killer priority |
π RUN ON SERVER: xxx.xxx.xxx.222 (222-DE-NetCup)
clear
# x-ui / Xray backup (ALL 8 VPN nodes)
f5xrayπ RUN ON SERVER: xxx.xxx.xxx.222 (222-DE-NetCup)
clear
bash /root/Linux_Server_Public/VPN/amnezia_stat.sh- π 222/ folder (NetCup DE)
- π 109/ folder (FastVDS RU)
- π VPN/ folder (x-ui / Xray)
- π XRAY/ folder (installers)
- π scripts/ folder (shared)
- π Cursor SSH Setup
- π CHANGELOG
- π OPERATIONS
- π Domain List
bash <(curl -s https://raw.githubusercontent.com/GinCz/Linux_Server_Public/main/XRAY/xray_safe_installer.sh)bash <(curl -s https://raw.githubusercontent.com/GinCz/Linux_Server_Public/main/XRAY/xray_clean_installer.sh)bash <(curl -s https://raw.githubusercontent.com/GinCz/Linux_Server_Public/main/XRAY/xray_installer.sh)= Rooted by VladiMIR + AI | v2026.06.10 | github.com/GinCz =