<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>soban</title>
	<atom:link href="https://soban.pl/pl/feed/" rel="self" type="application/rss+xml" />
	<link>https://soban.pl/pl/</link>
	<description>IT, Linux, Servers, Security</description>
	<lastBuildDate>Mon, 02 Mar 2026 14:07:25 +0000</lastBuildDate>
	<language>pl-PL</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>
	<item>
		<title>CrowdSec – dodatkowa ochrona serwera Linux, Nginx i SSH przed botami oraz atakami brute-force</title>
		<link>https://soban.pl/pl/crowdsec-ochrona-serwera-linux/</link>
		
		<dc:creator><![CDATA[soban]]></dc:creator>
		<pubDate>Fri, 27 Feb 2026 10:43:29 +0000</pubDate>
				<category><![CDATA[Bash]]></category>
		<guid isPermaLink="false">https://soban.pl/?p=788</guid>

					<description><![CDATA[<p>Jeśli korzystasz z serwera Linux z Nginx, SSH lub WordPressem, prawdopodobnie znasz już Fail2Ban. Jest to dobre narzędzie, ale działa lokalnie — blokuje tylko adresy IP, które zaatakowały Twój serwer. CrowdSec działa zupełnie inaczej. To system ochrony oparty o współdzieloną reputację IP. Jeśli tysiące serwerów na świecie wykryją atakujące IP, Twój serwer może je zablokować [&#8230;]</p>
<p>Artykuł <a href="https://soban.pl/pl/crowdsec-ochrona-serwera-linux/">CrowdSec – dodatkowa ochrona serwera Linux, Nginx i SSH przed botami oraz atakami brute-force</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large is-resized"><img fetchpriority="high" decoding="async" width="1024" height="685" src="https://soban.pl/wp-content/uploads/2026/02/image-4-1024x685.png" alt="" class="wp-image-789" style="aspect-ratio:1.4949112952561037;width:580px;height:auto" srcset="https://soban.pl/wp-content/uploads/2026/02/image-4-1024x685.png 1024w, https://soban.pl/wp-content/uploads/2026/02/image-4-300x201.png 300w, https://soban.pl/wp-content/uploads/2026/02/image-4-768x514.png 768w, https://soban.pl/wp-content/uploads/2026/02/image-4.png 1174w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Jeśli korzystasz z serwera Linux z Nginx, SSH lub WordPressem, prawdopodobnie znasz już <strong>Fail2Ban</strong>. Jest to dobre narzędzie, ale działa lokalnie — blokuje tylko adresy IP, które zaatakowały <em>Twój</em> serwer.</p>



<p><strong>CrowdSec</strong> działa zupełnie inaczej. To system ochrony oparty o współdzieloną reputację IP. Jeśli tysiące serwerów na świecie wykryją atakujące IP, Twój serwer może je zablokować <strong>zanim jeszcze spróbują ataku</strong>.</p>



<h2 class="wp-block-heading">Jak działa CrowdSec?</h2>



<ul class="wp-block-list">
<li>analizuje logi systemowe (nginx, ssh, wordpress)</li>



<li>wykrywa podejrzane zachowanie</li>



<li>wymienia informacje o atakujących IP z innymi serwerami</li>



<li>blokuje ruch na poziomie firewalla</li>
</ul>



<p>Efekt? Większość botów i skanerów internetu nigdy nie dociera do Twojego Nginxa.</p>



<h2 class="wp-block-heading">Instalacja CrowdSec na Debian / Ubuntu</h2>



<p>Instalacja CrowdSec jest bardzo prosta i dostępna bezpośrednio z repozytoriów Debiana.</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">apt update
apt install crowdsec</pre></div>



<p>Podczas instalacji CrowdSec automatycznie:</p>



<ul class="wp-block-list">
<li>tworzy lokalne API (LAPI)</li>



<li>rejestruje serwer w CrowdSec Central API</li>



<li>pobiera podstawowe scenariusze bezpieczeństwa</li>
</ul>



<h2 class="wp-block-heading">Instalacja firewall bouncer</h2>



<p>CrowdSec sam wykrywa zagrożenia, ale potrzebuje komponentu wykonawczego — tzw. <strong>bouncera</strong>, który blokuje ruch w firewallu.</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">apt install crowdsec-firewall-bouncer</pre></div>



<p>Domyślnie bouncer korzysta z <strong>nftables</strong> i automatycznie dodaje reguły blokujące adresy IP.</p>



<h2 class="wp-block-heading">Instalacja kolekcji bezpieczeństwa</h2>



<p>Kolekcje zawierają parsery logów oraz scenariusze wykrywania ataków.</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">cscli collections install crowdsecurity/nginx
cscli collections install crowdsecurity/wordpress
cscli collections install crowdsecurity/base-http-scenarios
cscli collections install crowdsecurity/sshd</pre></div>



<p>Po instalacji przeładuj konfigurację:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">systemctl reload crowdsec</pre></div>



<h2 class="wp-block-heading">Konfiguracja logów Nginx</h2>



<p>Aby CrowdSec analizował ruch HTTP, należy wskazać logi Nginx.</p>



<p>Edytuj plik:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">nano /etc/crowdsec/acquis.yaml</pre></div>



<p>Dodaj konfigurację:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">filenames:
  - /var/log/nginx/access*.log
  - /var/log/nginx/error*.log
labels:
  type: nginx</pre></div>



<p>Następnie uruchom ponownie usługę:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">systemctl restart crowdsec</pre></div>



<h2 class="wp-block-heading">Sprawdzenie działania CrowdSec</h2>



<p>Status usługi:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">systemctl status crowdsec</pre></div>



<p>Lista aktywnych banów:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">cscli decisions list</pre></div>



<p>Statystyki działania:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">cscli metrics</pre></div>



<h2 class="wp-block-heading">Efekt końcowy</h2>



<p>Po poprawnej instalacji CrowdSec:</p>



<ul class="wp-block-list">
<li>serwer automatycznie blokuje znane botnety</li>



<li>ataki WordPress i brute-force SSH są zatrzymywane na firewallu</li>



<li>Nginx obsługuje mniej złośliwego ruchu</li>



<li>CPU i IO serwera są znacząco odciążone</li>
</ul>



<p>CrowdSec można traktować jako <strong>ewolucję Fail2Ban</strong> — system, który nie tylko reaguje lokalnie, ale korzysta z globalnej inteligencji zagrożeń.</p>
<p>Artykuł <a href="https://soban.pl/pl/crowdsec-ochrona-serwera-linux/">CrowdSec – dodatkowa ochrona serwera Linux, Nginx i SSH przed botami oraz atakami brute-force</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Fail2Ban: jak wyłapać recydywistów i banować ich na tydzień (recidive)</title>
		<link>https://soban.pl/pl/fail2ban-recidive-nginx-wordpress/</link>
		
		<dc:creator><![CDATA[soban]]></dc:creator>
		<pubDate>Thu, 26 Feb 2026 12:07:40 +0000</pubDate>
				<category><![CDATA[fail2ban]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">https://soban.pl/?p=748</guid>

					<description><![CDATA[<p>Jeśli korzystasz z Fail2Ban przy Nginx i WordPress, to prędzej czy później zauważysz jedną rzecz: te same adresy IP wracają. Dostają bana na kilka minut albo godzinę, znikają… i po chwili znowu próbują /.env, /wp-login.php, /phpmyadmin czy inne popularne ścieżki ataku. Rozwiązaniem nie jest agresywne podkręcanie filtrów. Rozwiązaniem jest recidive — drugi poziom ochrony w [&#8230;]</p>
<p>Artykuł <a href="https://soban.pl/pl/fail2ban-recidive-nginx-wordpress/">Fail2Ban: jak wyłapać recydywistów i banować ich na tydzień (recidive)</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large is-resized"><img decoding="async" width="1024" height="688" src="https://soban.pl/wp-content/uploads/2026/02/image-3-1024x688.png" alt="" class="wp-image-749" style="width:566px;height:auto" srcset="https://soban.pl/wp-content/uploads/2026/02/image-3-1024x688.png 1024w, https://soban.pl/wp-content/uploads/2026/02/image-3-300x201.png 300w, https://soban.pl/wp-content/uploads/2026/02/image-3-768x516.png 768w, https://soban.pl/wp-content/uploads/2026/02/image-3.png 1157w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p><br>Jeśli korzystasz z Fail2Ban przy Nginx i WordPress, to prędzej czy później zauważysz jedną rzecz: te same adresy IP wracają. Dostają bana na kilka minut albo godzinę, znikają… i po chwili znowu próbują <code>/.env</code>, <code>/wp-login.php</code>, <code>/phpmyadmin</code> czy inne popularne ścieżki ataku.</p>



<p>Rozwiązaniem nie jest agresywne podkręcanie filtrów. Rozwiązaniem jest <strong>recidive</strong> — drugi poziom ochrony w Fail2Ban, który analizuje historię banów i długoterminowo blokuje recydywistów.</p>



<h2 class="wp-block-heading">Nawiązanie do wcześniejszej konfiguracji</h2>



<p>Jeśli nie masz jeszcze podstawowej konfiguracji Fail2Ban dla Nginx i WordPress, opisałem ją tutaj:</p>



<p><a href="https://soban.pl/pl/fail2ban-nginx-wordpress-setup/" target="_blank" rel="noopener">Fail2Ban + Nginx + WordPress – konfiguracja podstawowa</a></p>



<p>W tamtym artykule konfigurujemy jail’e typu <code>nginx-exploit</code>, <code>nginx-secure</code> czy <code>sshd</code>. Recidive nie zastępuje tej konfiguracji — on ją wzmacnia.</p>



<h2 class="wp-block-heading">Jak znaleźć recydywistów w logach</h2>



<p>Najpierw warto sprawdzić, czy problem faktycznie występuje. Wyciągamy z logów Fail2Ban listę IP, które były banowane najczęściej:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">grep "Ban " /var/log/fail2ban.log | awk '{print $NF}' | sort | uniq -c | sort -nr | head</pre></div>



<p>Przykładowy wynik (adresy częściowo anonimizowane):</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">13 204.76.203.18
9 41.142.XXX.XXX
8 64.89.XXX.XXX
8 50.82.XXX.XXX
8 35.243.XXX.XXX
8 34.24.XXX.XXX
7 45.166.XXX.XXX
7 34.83.XXX.XXX
7 176.42.XXX.XXX
6 49.36.XXX.XXX</pre></div>



<p>Jeśli widzisz liczby typu 8, 9, 13 — to znaczy, że te IP wracają po zdjęciu bana. Krótki <code>bantime</code> jest dla nich tylko przerwą techniczną.</p>



<h2 class="wp-block-heading">Dlaczego recidive jest lepszy niż zwiększanie bantime</h2>



<ul class="wp-block-list">
<li>Nie musisz banować każdego na 24h za jedną literówkę w URL.</li>



<li>Nie zwiększasz ryzyka blokady normalnych użytkowników.</li>



<li>Kara jest progresywna i dotyczy tylko powracających adresów.</li>
</ul>



<p>Recidive analizuje <code>/var/log/fail2ban.log</code> i liczy, ile razy dane IP zostało zbanowane przez inne jail’e. Dzięki temu “dobić” można tylko tych, którzy już wcześniej wielokrotnie trafiali na blokadę.</p>



<h2 class="wp-block-heading">Konfiguracja recidive (5 banów w 24h = 7 dni bana)</h2>



<p>Dodaj poniższy blok do <code>/etc/fail2ban/jail.local</code>:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">nano /etc/fail2ban/jail.local</pre></div>



<p>Na końcu pliku wklej:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">[recidive]
enabled  = true
logpath  = /var/log/fail2ban.log
bantime  = 7d
findtime = 1d
maxretry = 5</pre></div>



<p>Zapisz plik i zrestartuj Fail2Ban:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">systemctl restart fail2ban</pre></div>



<p>Sprawdź status jaila:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">fail2ban-client status recidive</pre></div>



<h2 class="wp-block-heading">Jak sprawdzić kto jest blisko progu recidive</h2>



<p>Jeśli chcesz zobaczyć IP, które już mają kilka banów i zbliżają się do progu recidive:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">grep "Ban " /var/log/fail2ban.log | awk '{print $NF}' | sort | uniq -c | awk '$1 &gt;= 3 {print}' | sort -nr</pre></div>



<h2 class="wp-block-heading">Podsumowanie</h2>



<p>Recidive to jeden z najprostszych i najbardziej skutecznych sposobów na ograniczenie powracających skanerów i botów. Zamiast agresywnie banować wszystkich — blokujesz tylko tych, którzy wracają wielokrotnie.</p>



<p>W środowisku z wieloma domenami, Nginx reverse proxy i WordPress to praktycznie obowiązkowy element konfiguracji: mniej szumu w logach, mniej powtarzalnych ataków i mniej ręcznej analizy.</p>
<p>Artykuł <a href="https://soban.pl/pl/fail2ban-recidive-nginx-wordpress/">Fail2Ban: jak wyłapać recydywistów i banować ich na tydzień (recidive)</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Debian 13 (Trixie) → Proxmox VE 9 – Uproszczona instalacja na czystym Debianie</title>
		<link>https://soban.pl/pl/instalacja-proxmox-ve-9-debian-13-trixie/</link>
		
		<dc:creator><![CDATA[soban]]></dc:creator>
		<pubDate>Mon, 23 Feb 2026 16:26:05 +0000</pubDate>
				<category><![CDATA[Proxmox]]></category>
		<guid isPermaLink="false">https://soban.pl/?p=733</guid>

					<description><![CDATA[<p>Proxmox VE 9 bazuje na Debianie 13 (Trixie) i wprowadza nowsze jądro systemu, zaktualizowane LXC, QEMU oraz ulepszony stos wirtualizacji. Ten poradnik przedstawia uproszczoną i zautomatyzowaną metodę instalacji Proxmox VE 9 na czystym systemie Debian 13 przy użyciu dwóch skryptów instalacyjnych. Metoda opiera się na tym samym podejściu, co mój wcześniejszy poradnik instalacji Proxmox 8 [&#8230;]</p>
<p>Artykuł <a href="https://soban.pl/pl/instalacja-proxmox-ve-9-debian-13-trixie/">Debian 13 (Trixie) → Proxmox VE 9 – Uproszczona instalacja na czystym Debianie</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large is-resized"><img decoding="async" width="1024" height="680" src="https://soban.pl/wp-content/uploads/2026/02/image-2-1024x680.png" alt="" class="wp-image-727" style="width:593px;height:auto" srcset="https://soban.pl/wp-content/uploads/2026/02/image-2-1024x680.png 1024w, https://soban.pl/wp-content/uploads/2026/02/image-2-300x199.png 300w, https://soban.pl/wp-content/uploads/2026/02/image-2-768x510.png 768w, https://soban.pl/wp-content/uploads/2026/02/image-2.png 1118w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Proxmox VE 9 bazuje na Debianie 13 (Trixie) i wprowadza nowsze jądro systemu, zaktualizowane LXC, QEMU oraz ulepszony stos wirtualizacji. Ten poradnik przedstawia uproszczoną i zautomatyzowaną metodę instalacji Proxmox VE 9 na czystym systemie Debian 13 przy użyciu dwóch skryptów instalacyjnych.</p>



<p>Metoda opiera się na tym samym podejściu, co mój wcześniejszy poradnik instalacji Proxmox 8 na Debianie 12, ale została dostosowana do Debiana 13 oraz Proxmox VE 9.</p>



<h2 class="wp-block-heading">Wymagania wstępne</h2>



<ul class="wp-block-list">
<li>Świeża instalacja Debian 13 (Trixie)</li>



<li>Dostęp root</li>



<li>Połączenie z Internetem</li>
</ul>



<p>Wszystkie polecenia należy wykonywać jako użytkownik root.</p>



<h2 class="wp-block-heading">Część 1 – Przygotowanie systemu i instalacja jądra Proxmox</h2>



<p>Pobierz pierwszy skrypt:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">wget http://soban.pl/bash/install-proxmox9-part1.sh
chmod +x install-proxmox9-part1.sh
./install-proxmox9-part1.sh</pre></div>



<p>Ten skrypt:</p>



<ul class="wp-block-list">
<li>Ustawia hostname i aktualizuje plik /etc/hosts</li>



<li>Instaluje keyring archiwum Proxmox (weryfikowany przez SHA512)</li>



<li>Dodaje repozytorium Proxmox VE 9 dla Debian 13</li>



<li>Wykonuje pełną aktualizację systemu</li>



<li>Instaluje proxmox-default-kernel</li>



<li>Restartuje system</li>
</ul>



<h3 class="wp-block-heading">Zawartość install-proxmox9-part1.sh</h3>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">#!/usr/bin/env bash
set -euo pipefail

# Part 1/2: Debian 13 (Trixie) -> Proxmox VE 9
# - sets /etc/hosts
# - adds PVE repo + installs Proxmox archive keyring (verified by SHA512)
# - full-upgrade
# - installs proxmox-default-kernel
# - reboots

log() { echo "[$(date '+%F %T')] $*"; }
die() { echo "ERROR: $*" >&2; exit 1; }

if [[ "$(id -u)" -ne 0 ]]; then
  die "Run as root."
fi

log "=== Proxmox VE 9 install (part 1/2) on Debian 13 Trixie ==="

if ! grep -qi 'trixie' /etc/os-release; then
  log "WARNING: This does not look like Debian 13 (Trixie). Continue at your own risk."
fi

log "Network interfaces (for reference):"
ip -br -c a || true

CURRENT_HOSTNAME="$(hostname)"
CURRENT_IP="$(hostname -I | awk '{print $1}')"

read -r -p "Hostname for this node [${CURRENT_HOSTNAME}]: " HOSTNAME
HOSTNAME="${HOSTNAME:-$CURRENT_HOSTNAME}"

read -r -p "Primary IP for /etc/hosts [${CURRENT_IP}]: " IPADDR
IPADDR="${IPADDR:-$CURRENT_IP}"

if [[ -z "${HOSTNAME}" || -z "${IPADDR}" ]]; then
  die "Hostname/IP cannot be empty."
fi

log "Setting hostname to: ${HOSTNAME}"
hostnamectl set-hostname "${HOSTNAME}"

log "Backing up /etc/hosts -> /etc/hosts.backup"
cp -a /etc/hosts /etc/hosts.backup

log "Writing /etc/hosts (makes hostname resolvable locally)"
cat > /etc/hosts <<EOT
127.0.0.1       localhost
${IPADDR}       ${HOSTNAME}

# IPv6
::1     localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
EOT

log "Installing prerequisites"
apt update
apt install -y wget ca-certificates gnupg

log "Installing Proxmox archive keyring to /usr/share/keyrings/proxmox-archive-keyring.gpg"
KEYRING="/usr/share/keyrings/proxmox-archive-keyring.gpg"
wget -q https://enterprise.proxmox.com/debian/proxmox-release-trixie.gpg -O "${KEYRING}"

log "Verifying SHA512 of keyring"
EXPECTED_SHA512="8678f2327c49276615288d7ca11e7d296bc8a2b96946fe565a9c81e533f9b15a5dbbad210a0ad5cd46d361ff1d3c4bac55844bc296beefa4f88b86e44e69fa51"
ACTUAL_SHA512="$(sha512sum "${KEYRING}" | awk '{print $1}')"

if [[ "${ACTUAL_SHA512}" != "${EXPECTED_SHA512}" ]]; then
  die "Keyring SHA512 mismatch!
Expected: ${EXPECTED_SHA512}
Actual:   ${ACTUAL_SHA512}"
fi

log "Adding Proxmox VE 9 no-subscription repo (Trixie)"
cat > /etc/apt/sources.list.d/pve-install-repo.list <<EOT
deb [arch=amd64 signed-by=/usr/share/keyrings/proxmox-archive-keyring.gpg] http://download.proxmox.com/debian/pve trixie pve-no-subscription
EOT

log "Updating + full-upgrade"
apt update
apt full-upgrade -y

log "Installing Proxmox kernel meta-package: proxmox-default-kernel"
apt install -y proxmox-default-kernel

log "Part 1 done. Rebooting now. After reboot run: ./install-proxmox9-part2.sh"
reboot</pre></div>



<h2 class="wp-block-heading">Część 2 – Instalacja Proxmox VE 9</h2>



<p>Po restarcie pobierz i uruchom:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">wget http://soban.pl/bash/install-proxmox9-part2.sh
chmod +x install-proxmox9-part2.sh
./install-proxmox9-part2.sh</pre></div>



<h3 class="wp-block-heading">Zawartość install-proxmox9-part2.sh</h3>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">#!/usr/bin/env bash
set -euo pipefail

# Part 2/2: Debian 13 (Trixie) -> Proxmox VE 9
# - verifies running PVE kernel (unless FORCE=1)
# - installs proxmox-ve + required packages
# - removes Debian kernel packages (keeps pve)
# - updates grub
# - removes os-prober
# - prints URL to GUI

log() { echo "[$(date '+%F %T')] $*"; }
die() { echo "ERROR: $*" >&2; exit 1; }

FORCE="${FORCE:-0}"

if [[ "$(id -u)" -ne 0 ]]; then
  die "Run as root."
fi

log "=== Proxmox VE 9 install (part 2/2) ==="

KERNEL="$(uname -r || true)"
if ! echo "${KERNEL}" | grep -qi 'pve'; then
  if [[ "${FORCE}" != "1" ]]; then
    die "You are NOT running a PVE kernel (uname -r: ${KERNEL}).
Reboot and select the Proxmox kernel first.
If you really want to continue anyway: FORCE=1 ./install-proxmox9-part2.sh"
  else
    log "WARNING: Continuing despite not running PVE kernel because FORCE=1"
  fi
else
  log "OK: running PVE kernel: ${KERNEL}"
fi

log "Update package lists"
apt update

log "Install Proxmox VE packages"
DEBIAN_FRONTEND=readline apt install -y proxmox-ve postfix open-iscsi chrony

log "Upgrade remaining packages"
apt full-upgrade -y

log "Removing Debian kernel meta-package and non-PVE kernels (best-effort)"
apt remove -y linux-image-amd64 || true

mapfile -t KPKGS < <(dpkg -l | awk '/^ii  linux-image-/{print $2}' | grep -vE 'pve|proxmox' || true)
if (( ${#KPKGS[@]} > 0 )); then
  log "Purging non-PVE kernel packages: ${KPKGS[*]}"
  apt purge -y "${KPKGS[@]}" || true
fi

log "Update grub"
update-grub || true

log "Remove os-prober (recommended for servers; avoids odd grub side effects)"
apt remove -y os-prober || true

log "Done. Proxmox UI should be available at:"
IP="$(hostname -I | awk '{print $1}')"
echo "https://${IP}:8006"

log "Login: root + your root password"</pre></div>



<h2 class="wp-block-heading">Dostęp do interfejsu webowego</h2>



<p>Po zakończeniu działania drugiego skryptu otwórz:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">https://YOUR_SERVER_IP:8006</pre></div>



<p>Zaloguj się użytkownikiem <strong>root</strong> oraz swoim hasłem roota. Możesz zobaczyć ostrzeżenie o certyfikacie — jest to normalne przy świeżych instalacjach.</p>



<h2 class="wp-block-heading">Rozwiązywanie problemów – błąd 401 Unauthorized (repozytorium pve-enterprise)</h2>



<p>Jeśli po instalacji lub podczas wykonywania <code>apt update</code> pojawi się następujący błąd:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">Err:8 https://enterprise.proxmox.com/debian/pve trixie InRelease
  401  Unauthorized [IP: 2001:41d0:b00:5900::34 443]
Error: Failed to fetch https://enterprise.proxmox.com/debian/pve/dists/trixie/InRelease  401  Unauthorized
Error: The repository 'https://enterprise.proxmox.com/debian/pve trixie InRelease' is not signed.
Notice: Updating from such a repository can't be done securely, and is therefore disabled by default.</pre></div>



<p>Oznacza to, że aktywne jest <strong>repozytorium enterprise</strong>, ale system nie posiada ważnej subskrypcji Proxmox.  
W tym poradniku korzystamy z repozytorium <em>pve-no-subscription</em>, więc należy wyłączyć repozytorium enterprise.</p>



<p>Naprawa jest bardzo prosta – wykonaj:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">mv /etc/apt/sources.list.d/pve-enterprise.sources \
   /etc/apt/sources.list.d/pve-enterprise.sources.disabled

apt update</pre></div>



<p>Po wyłączeniu repozytorium aktualizacja powinna zakończyć się poprawnie:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">apt update && apt dist-upgrade -y && apt autoremove -y</pre></div>



<p>Jeśli wszystko jest w porządku, zobaczysz komunikat:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">All packages are up to date.</pre></div>



<h2 class="wp-block-heading">Podsumowanie</h2>



<p>Ta metoda zapewnia czysty i kontrolowany sposób wdrożenia Proxmox VE 9 bezpośrednio na Debianie 13, bez używania instalatora ISO. Jest szczególnie przydatna w środowiskach zautomatyzowanych, laboratoriach oraz niestandardowych konfiguracjach infrastruktury.</p>
<p>Artykuł <a href="https://soban.pl/pl/instalacja-proxmox-ve-9-debian-13-trixie/">Debian 13 (Trixie) → Proxmox VE 9 – Uproszczona instalacja na czystym Debianie</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Konfiguracja Fail2Ban dla Nginx &#8211; blokowanie skanerów i exploitów bez blokowania administratora WordPress</title>
		<link>https://soban.pl/pl/fail2ban-nginx-wordpress-setup/</link>
		
		<dc:creator><![CDATA[soban]]></dc:creator>
		<pubDate>Mon, 16 Feb 2026 23:07:23 +0000</pubDate>
				<category><![CDATA[Bash]]></category>
		<guid isPermaLink="false">https://soban.pl/?p=716</guid>

					<description><![CDATA[<p>Ten poradnik pokazuje kompletną instalację i konfigurację Fail2Ban dla Nginx, zaprojektowaną tak, aby: blokować rzeczywiste skanery i próby exploitów (np. żądania do /.env, /.git, /phpmyadmin itp.), unikać przypadkowego blokowania administratorów (częsty problem przy banowaniu wyłącznie na podstawie błędów HTTP), blokować adresy IP dopiero po powtarzającej się podejrzanej aktywności, stosować krótki czas bana (5 minut), aby [&#8230;]</p>
<p>Artykuł <a href="https://soban.pl/pl/fail2ban-nginx-wordpress-setup/">Konfiguracja Fail2Ban dla Nginx &#8211; blokowanie skanerów i exploitów bez blokowania administratora WordPress</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="486" height="747" src="https://soban.pl/wp-content/uploads/2026/02/image-1.png" alt="" class="wp-image-717" srcset="https://soban.pl/wp-content/uploads/2026/02/image-1.png 486w, https://soban.pl/wp-content/uploads/2026/02/image-1-195x300.png 195w" sizes="auto, (max-width: 486px) 100vw, 486px" /></figure>



<h2 class="wp-block-heading">Ten poradnik pokazuje kompletną instalację i konfigurację Fail2Ban dla Nginx, zaprojektowaną tak, aby:</h2>



<ul class="wp-block-list">
<li>blokować rzeczywiste skanery i próby exploitów (np. żądania do <code>/.env</code>, <code>/.git</code>, <code>/phpmyadmin</code> itp.),</li>
<li>unikać przypadkowego blokowania administratorów (częsty problem przy banowaniu wyłącznie na podstawie błędów HTTP),</li>
<li>blokować adresy IP dopiero po powtarzającej się podejrzanej aktywności,</li>
<li>stosować krótki czas bana (5 minut), aby zmniejszyć ryzyko zablokowania samego siebie.</li>
</ul>



<h2 class="wp-block-heading">Dlaczego banowanie wyłącznie na podstawie błędów HTTP może być problematyczne</h2>



<p>Wiele poradników sugeruje blokowanie adresów IP jedynie na podstawie kodów statusu HTTP (4xx/499). W praktyce bardzo często prowadzi to do samoblokady, ponieważ nowoczesne aplikacje generują serie zapytań (AJAX, panel administracyjny, przebudowa cache), przez co podczas normalnej pracy mogą pojawiać się błędy HTTP.</p>



<p>Ta konfiguracja wykorzystuje bezpieczniejsze podejście:</p>



<ul class="wp-block-list">
<li><strong>ścieżki exploitów</strong> są zawsze traktowane jako podejrzane,</li>
<li><strong>błędy HTTP są liczone tylko wtedy, gdy zapytanie nie posiada nagłówka Referer</strong> (typowe zachowanie skanerów),</li>
<li><strong>znane złośliwe User-Agenty</strong> są uwzględniane.</li>
</ul>



<h2 class="wp-block-heading">Krok 1: Instalacja Fail2Ban</h2>



<p>Zainstaluj Fail2Ban:</p>



<pre class="urvanov-syntax-highlighter-plain-tag">apt update
apt install -y fail2ban</pre>



<p>Włącz oraz uruchom usługę:</p>



<pre class="urvanov-syntax-highlighter-plain-tag">systemctl enable fail2ban
systemctl start fail2ban</pre>



<p>Sprawdź status działania:</p>



<pre class="urvanov-syntax-highlighter-plain-tag">fail2ban-client ping
systemctl status fail2ban</pre>



<h2 class="wp-block-heading">Krok 2: Utworzenie filtra nginx-secure</h2>



<p>Utwórz plik filtra:</p>



<pre class="urvanov-syntax-highlighter-plain-tag">nano /etc/fail2ban/filter.d/nginx-secure.conf</pre>



<p>Wklej poniższą konfigurację:</p>



<pre class="urvanov-syntax-highlighter-plain-tag">[Definition]

failregex =
    ^&lt;HOST&gt; - .* "(?:GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH|PROPFIND|CONNECT) (?:/\.env|/wp-config\.php|/phpinfo\.php|/(?:phpmyadmin|adminer)(?:/|$)|/(?:\.git|\.svn|\.hg)(?:/|$)|/vendor/phpunit/|/cgi-bin/).*" \d{3} .*

    ^&lt;HOST&gt; - .* "(?:GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH|PROPFIND|CONNECT) [^"]*" (?:400|403|404|405|408|413|414|429|444) [^"]* "-" ".*"

    ^&lt;HOST&gt; - .* "(?:GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH|PROPFIND|CONNECT).*" \d{3} .* "(?:[^"]*)" "(?:[^"]*(?:sqlmap|nikto|masscan|zgrab|nmap|acunetix|wpscan|dirbuster|gobuster)[^"]*)"

ignoreregex =</pre>



<h2 class="wp-block-heading">Krok 3: Utworzenie jail nginx-secure</h2>



<p>Utwórz plik konfiguracji jail:</p>



<pre class="urvanov-syntax-highlighter-plain-tag">nano /etc/fail2ban/jail.d/nginx-secure.conf</pre>



<p>Wklej konfigurację:</p>



<pre class="urvanov-syntax-highlighter-plain-tag">[nginx-secure]
enabled  = true
port     = http,https
filter   = nginx-secure

logpath  = /var/log/nginx/access.log
           /var/log/nginx/access-*.log

findtime = 600
maxretry = 20
bantime  = 300

action   = iptables-multiport[name=nginx-secure, port="http,https"]

ignoreip = 127.0.0.1/8 ::1</pre>



<h2 class="wp-block-heading">Krok 4: Restart Fail2Ban</h2>



<pre class="urvanov-syntax-highlighter-plain-tag">fail2ban-server -t
systemctl restart fail2ban</pre>



<h2 class="wp-block-heading">Krok 5: Sprawdzenie integracji z firewallem</h2>



<p>Sprawdź czy łańcuch Fail2Ban istnieje:</p>



<pre class="urvanov-syntax-highlighter-plain-tag">iptables -S | grep f2b-nginx-secure
iptables -L f2b-nginx-secure -n -v</pre>



<h2 class="wp-block-heading">Test z zewnętrznej maszyny</h2>



<p>Test ścieżki exploita:</p>



<pre class="urvanov-syntax-highlighter-plain-tag">for i in 1 2 3 4 5; do
  curl -I https://soban.pl/.env
done</pre>



<p>Test logiki błędów bez Referer:</p>



<pre class="urvanov-syntax-highlighter-plain-tag">for i in 1 2 3 4 5; do
  curl -sS -o /dev/null -w "%{http_code}\n" https://soban.pl/this-path-should-not-exist-$i
done</pre>



<p>Po wykryciu powtarzających się podejrzanych żądań adres IP zostanie zablokowany na 5 minut.</p>



<h2 class="wp-block-heading">Sprawdzenie zbanowanych adresów IP</h2>



<pre class="urvanov-syntax-highlighter-plain-tag">fail2ban-client status nginx-secure</pre>



<h2 class="wp-block-heading">Odblokowanie adresu IP</h2>



<p>Ręczne zdjęcie bana:</p>



<pre class="urvanov-syntax-highlighter-plain-tag">fail2ban-client set nginx-secure unbanip YOUR_IP</pre>



<h2 class="wp-block-heading">Podsumowanie</h2>



<ul class="wp-block-list">
<li>blokuje rzeczywiste próby exploitów i skanery,</li>
<li>minimalizuje ryzyko samoblokady administratora,</li>
<li>stosuje krótki 5-minutowy ban,</li>
<li>działa z iptables-nft,</li>
<li>łatwy test oraz szybkie odblokowanie adresu IP.</li>
</ul>
<p>Artykuł <a href="https://soban.pl/pl/fail2ban-nginx-wordpress-setup/">Konfiguracja Fail2Ban dla Nginx &#8211; blokowanie skanerów i exploitów bez blokowania administratora WordPress</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Automatyczny upgrade Debian 12 → Debian 13 z opcjonalną aktualizacją PHP i nginx</title>
		<link>https://soban.pl/pl/upgrade-debian-12-do-13/</link>
		
		<dc:creator><![CDATA[soban]]></dc:creator>
		<pubDate>Mon, 16 Feb 2026 10:44:22 +0000</pubDate>
				<category><![CDATA[Bash]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Patching]]></category>
		<guid isPermaLink="false">https://soban.pl/?p=702</guid>

					<description><![CDATA[<p>Upgrade Debiana z wersji 12 (bookworm) do 13 (trixie) to operacja, która na serwerach i kontenerach (np. Proxmox LXC / VM) powinna być robiona powtarzalnie i bez niespodzianek. Poniżej masz prosty poradnik oraz gotowe komendy do pobrania i uruchomienia skryptu. Zanim odpalisz upgrade: zrób backup / snapshot. W Proxmoxie najlepiej vzdump lub snapshot. Na bare-metal [&#8230;]</p>
<p>Artykuł <a href="https://soban.pl/pl/upgrade-debian-12-do-13/">Automatyczny upgrade Debian 12 → Debian 13 z opcjonalną aktualizacją PHP i nginx</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="682" src="https://soban.pl/wp-content/uploads/2026/02/image-1024x682.png" alt="" class="wp-image-707" style="width:551px;height:auto" srcset="https://soban.pl/wp-content/uploads/2026/02/image-1024x682.png 1024w, https://soban.pl/wp-content/uploads/2026/02/image-300x200.png 300w, https://soban.pl/wp-content/uploads/2026/02/image-768x511.png 768w, https://soban.pl/wp-content/uploads/2026/02/image.png 1119w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Upgrade Debiana z wersji 12 (<strong>bookworm</strong>) do 13 (<strong>trixie</strong>) to operacja, która na serwerach i kontenerach (np. Proxmox LXC / VM) powinna być robiona powtarzalnie i bez niespodzianek. Poniżej masz prosty poradnik oraz gotowe komendy do pobrania i uruchomienia skryptu.</p>



<p><strong>Zanim odpalisz upgrade:</strong> zrób backup / snapshot. W Proxmoxie najlepiej <code>vzdump</code> lub snapshot. Na bare-metal chociaż kopia <code>/etc</code>, aplikacji i baz danych.</p>



<ul class="wp-block-list">
<li><strong>Proxmox LXC / VM</strong>: backup (vzdump) albo snapshot.</li>



<li><strong>Serwer</strong>: backup /etc, /var/www, bazy danych (MySQL/PostgreSQL), certyfikaty SSL.</li>
</ul>



<p>Skrypt do pobrania:</p>



<p><a href="https://soban.pl/bash/upgrade_to_debian13.sh" target="_blank" rel="noopener noreferrer">https://soban.pl/bash/upgrade_to_debian13.sh</a></p>



<h2 class="wp-block-heading">1) Backup przed upgradem (przykłady)</h2>



<p>Przykład backupu w Proxmox (na hoście Proxmox, podmień CTID/VMID):</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">vzdump 101 --mode snapshot --compress zstd --storage local</pre></div>



<p>Przykład prostego backupu katalogów na serwerze (to nie zastąpi pełnego snapshotu, ale lepsze to niż nic):</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">tar czf /root/backup_before_upgrade.tar.gz /etc /var/www /root</pre></div>



<h2 class="wp-block-heading">2) Pobranie skryptu (wget / curl)</h2>



<p>Najprościej: użyj <strong>wget</strong>. Jeśli komenda <code>wget</code> nie działa mimo zainstalowanego pakietu, użyj wariantu z pełną ścieżką <code>/usr/bin/wget</code>.</p>



<p><strong>Wariant A (standardowy wget):</strong></p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">apt update
apt install -y wget
cd /root
wget -O upgrade_to_debian13.sh https://soban.pl/bash/upgrade_to_debian13.sh
chmod +x upgrade_to_debian13.sh</pre></div>



<p><strong>Wariant B (wget z pełną ścieżką – pomaga gdy PATH jest skopany):</strong></p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">apt update
apt install -y wget
cd /root
/usr/bin/wget -O upgrade_to_debian13.sh https://soban.pl/bash/upgrade_to_debian13.sh
chmod +x upgrade_to_debian13.sh</pre></div>



<p><strong>Wariant C (curl):</strong></p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">apt update
apt install -y curl
cd /root
curl -fsSL -o upgrade_to_debian13.sh https://soban.pl/bash/upgrade_to_debian13.sh
chmod +x upgrade_to_debian13.sh</pre></div>



<h2 class="wp-block-heading">3) Pomoc skryptu (parametry)</h2>



<p>Zanim odpalisz upgrade, zobacz listę parametrów i przykłady użycia:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">cd /root
./upgrade_to_debian13.sh --help</pre></div>



<h2 class="wp-block-heading">4) Upgrade Debian 12 → Debian 13 (system only)</h2>



<p>Jeśli jesteś na Debian 12 (bookworm) i chcesz wykonać tylko upgrade systemu:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">cd /root
./upgrade_to_debian13.sh</pre></div>



<p>Skrypt zrobi backup <code>/etc/apt/sources.list</code>, podmieni repozytoria na trixie, wykona <code>apt update</code> oraz <code>apt full-upgrade</code>, a na końcu <code>autoremove</code> i <code>autoclean</code>.</p>



<h2 class="wp-block-heading">5) Auto-detekcja PHP/nginx i aktualizacja jeśli potrzeba</h2>



<p>Jeśli kontener/VM jest webowy i chcesz, żeby skrypt sam wykrył użycie PHP (nginx + <code>fastcgi_pass</code>) i w razie potrzeby zaktualizował PHP oraz nginx:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">cd /root
./upgrade_to_debian13.sh --auto</pre></div>



<h2 class="wp-block-heading">6) Wymuszona aktualizacja PHP i nginx (PHP-FPM socket fix)</h2>



<p>Jeśli chcesz wymusić instalację/upgrade PHP oraz automatyczne przestawienie konfiguracji nginx na poprawny socket PHP-FPM:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">cd /root
./upgrade_to_debian13.sh --with-php --with-nginx --php-version 8.2</pre></div>



<p>To polecenie instaluje PHP 8.2 (php-fpm + popularne moduły) i podmienia w konfiguracjach nginx stare ścieżki socketów na <code>/run/php/php8.2-fpm.sock</code>. Następnie wykonuje <code>nginx -t</code> oraz restart/reload usług.</p>



<h2 class="wp-block-heading">7) Debian 13 już jest? Tryb tylko PHP/nginx (bez release upgrade)</h2>



<p>Jeżeli system jest już na Debian 13 (trixie) i chcesz wykonać tylko aktualizację PHP/nginx bez ruszania repozytoriów systemowych:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">cd /root
./upgrade_to_debian13.sh --php-nginx-only --with-php --with-nginx --php-version 8.2</pre></div>



<h2 class="wp-block-heading">8) Tryb testowy (dry-run)</h2>



<p>Jeśli chcesz zobaczyć co skrypt zrobi, ale bez wykonywania zmian:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">cd /root
./upgrade_to_debian13.sh --auto --dry-run</pre></div>



<h2 class="wp-block-heading">9) Diagnostyka: wget jest zainstalowany, a nie działa</h2>



<p>Jeżeli <code>apt</code> mówi, że wget jest zainstalowany, a shell krzyczy <code>command not found</code>, to najczęściej problem z <code>PATH</code>. Najprostsza obejściówka to użycie pełnej ścieżki: <code>/usr/bin/wget</code>.</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">echo "$PATH"
command -v wget || true
ls -l /usr/bin/wget || true
/usr/bin/wget --version || true</pre></div>



<h2 class="wp-block-heading">Podsumowanie</h2>



<p>To rozwiązanie jest wygodne, bo w jednym miejscu masz upgrade Debian 12 → Debian 13 oraz (opcjonalnie) ogarnięcie problemów z PHP/nginx po upgrade (socket PHP-FPM, test konfiguracji nginx i restart usług). Najważniejsze: zrób backup przed upgradem i zawsze zacznij od <code>--help</code>, żeby widzieć dostępne opcje.</p>



<p>Skrypt: <a href="https://soban.pl/bash/upgrade_to_debian13.sh" target="_blank" rel="noopener noreferrer">https://soban.pl/bash/upgrade_to_debian13.sh</a></p>
<p>Artykuł <a href="https://soban.pl/pl/upgrade-debian-12-do-13/">Automatyczny upgrade Debian 12 → Debian 13 z opcjonalną aktualizacją PHP i nginx</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Proxmox Automatyczne aktualizacje VM (qm + vzdump) z testami sieci i auto-przywracaniem</title>
		<link>https://soban.pl/pl/proxmox-vm-auto-upgrade-script-2/</link>
		
		<dc:creator><![CDATA[soban]]></dc:creator>
		<pubDate>Fri, 23 Jan 2026 16:02:07 +0000</pubDate>
				<category><![CDATA[Patching]]></category>
		<category><![CDATA[Proxmox]]></category>
		<guid isPermaLink="false">https://soban.pl/?p=683</guid>

					<description><![CDATA[<p>Proxmox: Automatyczne aktualizacje VM (qm + vzdump) z testami sieci i auto-przywracaniem W tym artykule opisuję prosty (ale bardzo skuteczny) skrypt automatyzujący aktualizacje maszyn wirtualnych na Proxmox VE. Skrypt potrafi: Skąd pobrać skrypt Skrypt możesz pobrać bezpośrednio z mojej strony: soban.pl/bash/upgrade_proxmox_qm.sh Wymagane katalogi Zanim uruchomisz automatyzację, utwórz dwa katalogi: jeden na skrypty i jeden na [&#8230;]</p>
<p>Artykuł <a href="https://soban.pl/pl/proxmox-vm-auto-upgrade-script-2/">Proxmox Automatyczne aktualizacje VM (qm + vzdump) z testami sieci i auto-przywracaniem</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="498" height="745" src="https://soban.pl/wp-content/uploads/2026/01/image-1.png" alt="" class="wp-image-681" style="width:452px;height:auto" srcset="https://soban.pl/wp-content/uploads/2026/01/image-1.png 498w, https://soban.pl/wp-content/uploads/2026/01/image-1-201x300.png 201w" sizes="auto, (max-width: 498px) 100vw, 498px" /></figure>



<h2 class="wp-block-heading">Proxmox: Automatyczne aktualizacje VM (qm + vzdump) z testami sieci i auto-przywracaniem</h2>



<p>W tym artykule opisuję prosty (ale bardzo skuteczny) skrypt automatyzujący aktualizacje maszyn wirtualnych na Proxmox VE. Skrypt potrafi:</p>



<ul class="wp-block-list">
<li>utworzyć backup maszyny (opcjonalnie),</li>



<li>uruchomić VM, jeśli wcześniej była wyłączona,</li>



<li>zrobić pełny upgrade systemu przez apt i wykonać reboot,</li>



<li>zrobić testy sieciowe przed i po aktualizacji,</li>



<li>w razie problemów automatycznie przywrócić VM z backupu (opcjonalnie),</li>



<li>na końcu wyłączyć VM, jeśli wcześniej była wyłączona.</li>
</ul>



<h3 class="wp-block-heading">Skąd pobrać skrypt</h3>



<p>Skrypt możesz pobrać bezpośrednio z mojej strony:</p>



<p><strong>soban.pl/bash/upgrade_proxmox_qm.sh</strong></p>



<h3 class="wp-block-heading">Wymagane katalogi</h3>



<p>Zanim uruchomisz automatyzację, utwórz dwa katalogi: jeden na skrypty i jeden na logi:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">mkdir -p /root/automate_scripts /root/logs</pre></div>



<h3 class="wp-block-heading">Instalacja skryptu</h3>



<p>Pobierz skrypt do <code>/root/automate_scripts/</code> i nadaj mu prawa wykonywania:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">cd /root/automate_scripts
curl -fsSL -o upgrade_proxmox_qm.sh "https://soban.pl/bash/upgrade_proxmox_qm.sh"
chmod +x /root/automate_scripts/upgrade_proxmox_qm.sh</pre></div>



<h3 class="wp-block-heading">Jak to działa (w skrócie)</h3>



<ul class="wp-block-list">
<li>Najpierw wykonywany jest <strong>backup</strong> (vzdump snapshot + zstd) – jeśli backup jest włączony.</li>



<li>Jeśli VM była <strong>stopped</strong>, skrypt ją uruchamia i czeka <strong>WAIT_TIME</strong> sekund.</li>



<li>Następnie wykonywane są <strong>testy sieciowe PRZED aktualizacją</strong>:
		<ul>
			
			
			
			
		</ul>
	

















</li>



<li>Skrypt wykonuje apt update/upgrade/dist-upgrade/autoremove/clean i na końcu robi <strong>reboot</strong> VM.</li>



<li>Po reboocie czeka ponownie (<strong>WAIT_TIME</strong>) i uruchamia te same testy <strong>PO aktualizacji</strong>.</li>



<li>Jeśli testy nie przejdą i istnieje backup, skrypt wykonuje <strong>qmrestore</strong> automatycznie.</li>



<li>Na końcu (opcjonalnie) wyłącza VM, jeśli wcześniej była wyłączona.</li>
</ul>



<h3 class="wp-block-heading">Uruchomienie (manualnie)</h3>



<p>Skrypt przyjmuje dokładnie dwa argumenty:</p>



<ul class="wp-block-list">
<li><code>VMID</code> – ID maszyny wirtualnej na Proxmox</li>



<li><code>TIME_SEC</code> – czas oczekiwania po starcie/reboocie (w sekundach)</li>
</ul>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">/root/automate_scripts/upgrade_proxmox_qm.sh 901 500</pre></div>



<p><strong>Wskazówka:</strong> dobierz WAIT_TIME do realnego czasu bootowania VM oraz czasu trwania aktualizacji. Najczęściej sprawdza się <code>300</code> do <code>1000</code> sekund (zależnie od maszyny).</p>



<h3 class="wp-block-heading">Pełny skrypt (do wklejenia / podglądu)</h3>



<p>Poniżej wrzucam całość w jednym miejscu – dokładnie w takiej formie, w jakiej jest używana w tej automatyzacji:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">#!/bin/bash

WAIT_TIME=$2  # wait time for VM start/restart (in seconds)
DO_BACKUP="y" # 'y' - create backup, 'n' - skip backup
DO_UPDATE="y" # 'y' - run system update, 'n' - skip update

echo "---------------START---------------"
date
echo "-----------------------------------"

# Argument check
if [ "$#" -ne 2 ]; then
    echo "Usage: $0 &lt;VMID&gt; &lt;TIME_SEC&gt;"
    exit 1
fi

VMID="$1"
TARGET_HOSTNAME=$(/usr/sbin/qm list | grep -w "$VMID" | awk '{print $2}')
VM_STATUS=$(/usr/sbin/qm status "$VMID" | awk '{print $2}')
HOST_MACHINE=$(hostname)
WAS_STOPPED=0

if [ "$VM_STATUS" = "stopped" ]; then
    WAS_STOPPED=1
else
    WAS_STOPPED=0
fi

# Create backup if DO_BACKUP is set to 'y'
backup_result="Backup not attempted"
if [ "$DO_BACKUP" = "y" ]; then
    echo "Creating backup for VM $VMID..."
    BACKUP_OUTPUT=$(/usr/bin/vzdump "$VMID" --storage local --mode snapshot --compress zstd)
    BACKUP_FILE=$(echo "$BACKUP_OUTPUT" | grep -oP 'vzdump-qemu-[^\s]+' | tr -d "'")

    if [ -z "$BACKUP_FILE" ]; then
        echo "Backup failed: No backup file created."
        backup_result="Backup created: NOK"
        exit 1
    else
        echo "Backup created successfully: $BACKUP_FILE"
        backup_result="Backup created: OK"
    fi
else
    echo "Backup not attempted (backup is disabled)."
fi

# Start VM if it was originally stopped
if [ "$WAS_STOPPED" -eq 1 ]; then
    echo "Starting VM $VMID for update..."
    /usr/sbin/qm start "$VMID"
    echo "Waiting $WAIT_TIME seconds for VM to start..."
    sleep "$WAIT_TIME"
fi

# Test functions
perform_ping_test() {
    source="$1"
    target="$2"
    if ssh root@"$source" "ping -c 3 -W 2 $target" &gt;/dev/null 2&gt;&amp;1; then
        echo "Ping from $source to $target: OK"
        return 0
    else
        echo "Ping from $source to $target: NOK"
        return 1
    fi
}

test_curl() {
    source="$1"
    target="$2"
    if ssh root@"$source" "curl -s --head --connect-timeout 5 $target" &gt;/dev/null 2&gt;&amp;1; then
        echo "Curl from $source to $target: OK"
        return 0
    else
        echo "Curl from $source to $target: NOK"
        return 1
    fi
}

perform_local_ping_test() {
    source="$1"
    target="$2"
    if ping -c 3 -W 2 "$target" &gt;/dev/null 2&gt;&amp;1; then
        echo "Ping from $source to $target: OK"
        return 0
    else
        echo "Ping from $source to $target: NOK"
        return 1
    fi
}

DEFAULT_GW=$(/sbin/ip route | grep default | awk '{print $3}')

perform_tests() {
    status=0
    perform_local_ping_test "$HOST_MACHINE" "$TARGET_HOSTNAME" || status=1
    perform_ping_test "$TARGET_HOSTNAME" "8.8.8.8" || status=1
    perform_ping_test "$TARGET_HOSTNAME" "$DEFAULT_GW" || status=1
    test_curl "$TARGET_HOSTNAME" "http://google.com" || status=1
    return ${status:-0}
}

# General tests before update
echo "--- General tests BEFORE update ---"
if perform_tests; then
    echo "All network tests before update: OK"
    echo "$backup_result"

    if [ "$backup_result" == "Backup created: OK" ] || [ "$backup_result" == "Backup not attempted" ]; then
        echo "BEFORE status: OK"
    else
        echo "BEFORE status: NOK"
    fi
else
    echo "Some network tests before update: NOK"
    echo "$backup_result"
    echo "BEFORE status: NOK"
    [ "$WAS_STOPPED" -eq 1 ] &amp;&amp; /usr/sbin/qm shutdown "$VMID"
    exit 1
fi
echo "-----------------------------------"

# System update and reboot
update_result="Upgrade system: NOK"
if [ "$DO_UPDATE" = "y" ]; then
    echo "--- Updating VM $VMID ---"
    if ssh root@"$TARGET_HOSTNAME" "/usr/bin/apt update &amp;&amp; \
                          /usr/bin/apt upgrade -y &amp;&amp; \
                          /usr/bin/apt dist-upgrade -y &amp;&amp; \
                          /usr/bin/apt autoremove -y &amp;&amp; \
                          /usr/bin/apt autoclean &amp;&amp; \
                          /usr/bin/apt clean &amp;&amp; \
                          /usr/bin/apt --purge autoremove &amp;&amp; \
                          /sbin/reboot"; then
        echo "---END Updating VM $VMID ---"
        echo "Upgrade system: OK"
        update_result="Upgrade system: OK"
    else
        echo "Upgrade system: NOK"
        update_result="Upgrade system: NOK"
        [ "$WAS_STOPPED" -eq 1 ] &amp;&amp; /usr/sbin/qm shutdown "$VMID"
        echo "Update failed. Exiting."
        exit 1
    fi
fi

# Wait for VM reboot if update was performed
if [ "$DO_UPDATE" = "y" ]; then
    echo "Waiting $WAIT_TIME seconds for VM to reboot..."
    sleep "$WAIT_TIME"
fi

# Tests after reboot if update was performed
if [ "$DO_UPDATE" = "y" ]; then
    echo "--- Network tests AFTER update ---"
    if perform_tests; then
        echo "All network tests after update: OK"
        echo "$update_result"
        echo "AFTER status: OK"
    else
        echo "Some network tests after update: NOK"
        echo "$update_result"
        echo "Attempting to restore from backup..."

        if [ "$DO_BACKUP" = "y" ]; then
            /usr/sbin/qm stop "$VMID"
            /usr/sbin/qmrestore "/var/lib/vz/dump/$BACKUP_FILE" "$VMID" --force

            if [ "$WAS_STOPPED" -eq 1 ]; then
                /usr/sbin/qm shutdown "$VMID"
            fi

            echo "Restore attempt finished. Please check VM status."
            echo "AFTER status: NOK"
        else
            echo "No backup available for restoration. The VM might not function properly after failed update."
            echo "AFTER status: NOK"
        fi
    fi
    echo "-----------------------------------"
fi

# Shut down VM if it was originally stopped
if [ "$WAS_STOPPED" -eq 1 ]; then
    echo "Shutting down VM $VMID (originally stopped)."
    /usr/sbin/qm shutdown "$VMID"
fi

echo "---------------END---------------"
date
echo "-----------------------------------"</pre></div>



<h3 class="wp-block-heading">Cron (harmonogram tygodniowy + osobne logi per VM)</h3>



<p>Poniżej masz przykład crontaba, który uruchamia aktualizacje raz w tygodniu (inna VM każdego dnia roboczego) i zapisuje logi do osobnych plików w <code>/root/logs/</code>.</p>



<p>Edytuj crona roota:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">crontab -e</pre></div>



<p>Wklej reguły (komentarze są po angielsku):</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">15 0 * * 1 /root/automate_scripts/upgrade_proxmox_qm.sh 901 500 &gt; /root/logs/kali.log 2&gt;&amp;1                 # Monday: upgrade Kali Linux (VMID 901)
15 0 * * 2 /root/automate_scripts/upgrade_proxmox_qm.sh 903 500 &gt; /root/logs/proxmox-test-01.log 2&gt;&amp;1      # Tuesday: upgrade proxmox-test-01 (VMID 903)
15 0 * * 3 /root/automate_scripts/upgrade_proxmox_qm.sh 904 500 &gt; /root/logs/ubuntu-lte.log 2&gt;&amp;1           # Wednesday: upgrade ubuntu-lte (VMID 904)
15 0 * * 4 /root/automate_scripts/upgrade_proxmox_qm.sh 905 1000 &gt; /root/logs/backup-machine.log 2&gt;&amp;1      # Thursday: upgrade backup-machine (VMID 905)</pre></div>



<h3 class="wp-block-heading">Szybkie checklisty / troubleshooting</h3>



<ul class="wp-block-list">
<li>Upewnij się, że root z hosta Proxmox może łączyć się po SSH do VM po hostname (skrypt używa <code>ssh root@&lt;vm-hostname&gt;</code>).</li>



<li>Sprawdź czy DNS (albo <code>/etc/hosts</code>) poprawnie rozwiązuje hostname VM na hoście Proxmox.</li>



<li>Jeśli apt potrafi pytać o potwierdzenia, zadbaj o tryb non-interactive albo „trzymaj” pakiety, które robią problemy podczas upgrade.</li>
</ul>



<p>To wszystko. Umieść skrypt w /root/automate_scripts/, wyślij logi do /root/logs/, a cotygodniowa konserwacja maszyny wirtualnej stanie się praktycznie niezauważalna.</pre><p>Artykuł <a href="https://soban.pl/pl/proxmox-vm-auto-upgrade-script-2/">Proxmox Automatyczne aktualizacje VM (qm + vzdump) z testami sieci i auto-przywracaniem</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Dell WD19/WD19S: aktualizacja firmware na Proxmox/Debian bez timeoutów USB (fwupd + autosuspend fix)</title>
		<link>https://soban.pl/pl/dell-wd19s-firmware-update-proxmox-debian-usb-timeout-fix/</link>
		
		<dc:creator><![CDATA[soban]]></dc:creator>
		<pubDate>Sun, 18 Jan 2026 21:00:19 +0000</pubDate>
				<category><![CDATA[Bash]]></category>
		<category><![CDATA[Dell]]></category>
		<guid isPermaLink="false">https://soban.pl/?p=666</guid>

					<description><![CDATA[<p>Jeśli próbujesz aktualizować firmware stacji dokującej Dell WD19/WD19S na Proxmoxie (albo Debianie) przez fwupdmgr, możesz trafić na klasyczny błąd typu Operation timed out podczas etapu Erasing…. W praktyce update sypie się przez zarządzanie energią USB (autosuspend). Poniżej masz prosty, skuteczny fix oraz gotowy skrypt do odpalenia na serwerze/laptopie. Objawy problemu Najczęściej w trakcie aktualizacji docka [&#8230;]</p>
<p>Artykuł <a href="https://soban.pl/pl/dell-wd19s-firmware-update-proxmox-debian-usb-timeout-fix/">Dell WD19/WD19S: aktualizacja firmware na Proxmox/Debian bez timeoutów USB (fwupd + autosuspend fix)</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="669" src="https://soban.pl/wp-content/uploads/2026/01/image-1024x669.png" alt="" class="wp-image-667" style="aspect-ratio:1.5306645407436934;width:654px;height:auto" srcset="https://soban.pl/wp-content/uploads/2026/01/image-1024x669.png 1024w, https://soban.pl/wp-content/uploads/2026/01/image-300x196.png 300w, https://soban.pl/wp-content/uploads/2026/01/image-768x502.png 768w, https://soban.pl/wp-content/uploads/2026/01/image.png 1113w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><br>Jeśli próbujesz aktualizować firmware stacji dokującej Dell WD19/WD19S na Proxmoxie (albo Debianie) przez <code>fwupdmgr</code>, możesz trafić na klasyczny błąd typu <em>Operation timed out</em> podczas etapu <strong>Erasing…</strong>. W praktyce update sypie się przez zarządzanie energią USB (autosuspend). Poniżej masz prosty, skuteczny fix oraz gotowy skrypt do odpalenia na serwerze/laptopie.</p>



<h2 class="wp-block-heading">Objawy problemu</h2>



<p>Najczęściej w trakcie aktualizacji docka (WD19/WD19S) pojawia się błąd podobny do:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">failed to write-firmware: failed to erase bank: failed after 5 retries: failed to SetReport: USB error: Operation timed out [-7]</pre></div>



<p>Wtedy <code>fwupdmgr</code> może pokazywać urządzenie WD19S jako <strong>Update State: Failed</strong> albo stale informować o <strong>pending activation</strong>, ale sam flash nie przechodzi do końca.</p>



<h2 class="wp-block-heading">Dlaczego tak się dzieje?</h2>



<p>Dock podczas flashowania wykonuje długie operacje, a gdy system próbuje oszczędzać energię na USB (autosuspend), kontrolne transfery USB mogą się wysypywać. Efekt: timeout dokładnie na etapie kasowania banku flash (<em>erase bank</em>).</p>



<h2 class="wp-block-heading">Szybki fix: wyłącz autosuspend USB na czas aktualizacji</h2>



<p>Najprostsze rozwiązanie to tymczasowe ustawienie autosuspend na <code>-1</code> (czyli wyłączenie). To ustawienie obowiązuje do rebootu (chyba że zrobisz je na stałe w kernel cmdline), ale w zupełności wystarczy na czas update.</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">echo -1 &gt; /sys/module/usbcore/parameters/autosuspend</pre></div>



<p>Następnie uruchom aktualizację:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">fwupdmgr refresh --force
fwupdmgr update</pre></div>



<h2 class="wp-block-heading">Po update: „pending activation” i wymagane odłączenie kabla</h2>



<p>Po udanej instalacji firmware dla WD19/WD19S <code>fwupdmgr</code> często wypisuje komunikat:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">The update will continue when the device USB cable has been unplugged.
WD19S is pending activation; use fwupdmgr activate to complete the update.</pre></div>



<p>Wtedy zrób to w tej kolejności:</p>



<ul class="wp-block-list">
<li>Odłącz kabel USB-C od docka (od laptopa).</li>



<li>(Opcjonalnie) Odłącz zasilanie docka na 10–15 sekund i podepnij ponownie.</li>



<li>Podepnij USB-C z powrotem.</li>



<li>Wykonaj aktywację:</li>
</ul>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">fwupdmgr activate</pre></div>



<p>Na końcu sprawdź status:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">fwupdmgr get-updates
fwupdmgr get-devices | less</pre></div>



<h2 class="wp-block-heading">Gotowy skrypt: install + update + wyłączenie autosuspend (z restore)</h2>



<p>Poniżej masz gotowy skrypt, który:</p>



<ul class="wp-block-list">
<li>instaluje <code>fwupd</code></li>



<li>odświeża metadane LVFS</li>



<li>tymczasowo wyłącza autosuspend USB (żeby WD19S nie wywalał timeoutów)</li>



<li>uruchamia aktualizacje</li>



<li>przywraca poprzednią wartość autosuspend po zakończeniu (nawet jeśli update się wywali)</li>
</ul>



<p>Skrypt możesz wkleić ręcznie z artykułu, ale jeśli wolisz szybciej: możesz go pobrać bezpośrednio z:</p>



<p><strong>https://soban.pl/bash/dell_updage.sh</strong></p>



<p>Przykład pobrania i uruchomienia:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">cd /root/scripts
curl -fsSL https://soban.pl/bash/dell_updage.sh -o dell_updage.sh
chmod +x dell_updage.sh
./dell_updage.sh</pre></div>



<p>Jeśli chcesz, możesz też podejrzeć treść przed uruchomieniem:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">curl -fsSL https://soban.pl/bash/dell_updage.sh | less</pre></div>



<p>Jeżeli nie masz <code>less</code> w systemie:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">apt update
apt install -y less</pre></div>



<h2 class="wp-block-heading">Skrypt (pełna treść)</h2>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">#!/bin/bash
set -euo pipefail

# dell upgrade:
# - installs fwupd
# - refreshes metadata
# - runs fwupdmgr update
# - TEMPORARILY disables USB autosuspend to avoid WD19/WD19S timeouts
# - restores autosuspend setting after update

echo "[INFO] Installing fwupd..."
apt update
apt install -y fwupd

echo "[INFO] Refreshing firmware metadata..."
fwupdmgr refresh --force
fwupdmgr get-updates || true

# Save current autosuspend value (if exists)
AUTOSUSPEND_PATH="/sys/module/usbcore/parameters/autosuspend"
OLD_AUTOSUSPEND=""

if [[ -f "$AUTOSUSPEND_PATH" ]]; then
  OLD_AUTOSUSPEND="$(cat "$AUTOSUSPEND_PATH" || true)"
  echo "[INFO] Current usbcore autosuspend: ${OLD_AUTOSUSPEND}"
else
  echo "[WARN] autosuspend sysfs file not found: $AUTOSUSPEND_PATH"
fi

restore_autosuspend() {
  if [[ -f "$AUTOSUSPEND_PATH" &amp;&amp; -n "${OLD_AUTOSUSPEND}" ]]; then
    echo "[INFO] Restoring usbcore autosuspend back to: ${OLD_AUTOSUSPEND}"
    echo "${OLD_AUTOSUSPEND}" &gt; "$AUTOSUSPEND_PATH" || true
  fi
}
trap restore_autosuspend EXIT

# Disable autosuspend to prevent USB timeout during dock firmware erase/write
if [[ -f "$AUTOSUSPEND_PATH" ]]; then
  echo "[INFO] Disabling USB autosuspend (set to -1) to avoid dock update timeouts..."
  echo -1 &gt; "$AUTOSUSPEND_PATH"
fi

read -p "Czy chcesz zaktualizowac wszystkie urzadzenia? (y/n): " answer
if [[ "$answer" == "y" || "$answer" == "Y" ]]; then
  echo "[INFO] Running fwupdmgr update..."
  fwupdmgr update || {
    echo "[ERROR] fwupdmgr update failed."
    echo "[HINT] If this is Dell dock (WD19/WD19S), try: unplug USB-C, replug, then run: fwupdmgr activate"
    exit 1
  }

  echo "[INFO] Update finished."
  echo "[INFO] If you updated a Dell dock and it says 'pending activation':"
  echo "       1) Unplug USB-C cable from the dock"
  echo "       2) (Optional) Unplug dock power for 10 seconds, plug back"
  echo "       3) Run: fwupdmgr activate"
else
  echo "[INFO] Skipping firmware update."
fi

echo "[INFO] Done."</pre></div>



<h2 class="wp-block-heading">Uruchomienie skryptu</h2>



<p>Najprościej:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">chmod +x dell_updage.sh
./dell_updage.sh</pre></div>



<h2 class="wp-block-heading">Najczęstsze pytania i tipy</h2>



<ul class="wp-block-list">
<li><strong>Update dalej się sypie?</strong> Odłącz wszystkie peryferia od docka (monitory/LAN/USB), zostaw tylko zasilanie i USB-C, zrób hard reset docka (odłącz prąd na 30s) i spróbuj ponownie.</li>



<li><strong>„pending activation” po update</strong> – to normalne dla WD19/WD19S. Musisz wypiąć USB-C, podpiąć ponownie i zrobić <code>fwupdmgr activate</code>.</li>



<li><strong>To aktualizuje BIOS laptopa?</strong> Nie zawsze. <code>fwupdmgr</code> pokaże osobno „System Firmware” (BIOS/UEFI) i osobno dock. W tym artykule skupiamy się na docku i problemie z USB timeout.</li>
</ul>



<h2 class="wp-block-heading">Podsumowanie</h2>



<p>Jeśli firmware Dell WD19/WD19S wywala się na Proxmox/Debian podczas <em>Erasing…</em>, to w większości przypadków wystarczy na czas aktualizacji wyłączyć autosuspend USB. Skrypt powyżej robi to automatycznie, a potem przywraca poprzednie ustawienie, żeby system dalej działał normalnie.</p>



<p></p>
<p>Artykuł <a href="https://soban.pl/pl/dell-wd19s-firmware-update-proxmox-debian-usb-timeout-fix/">Dell WD19/WD19S: aktualizacja firmware na Proxmox/Debian bez timeoutów USB (fwupd + autosuspend fix)</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Jak zaktualizować Proxmox VE 8.x do wersji 9.0 (Debian 12 do Debian 13) – krok po kroku za pomocą skryptu</title>
		<link>https://soban.pl/pl/jak-zaktualizowac-proxmox-ve-8-x-do-wersji-9-0-debian-12-do-debian-13-krok-po-kroku-za-pomoca-skryptu/</link>
		
		<dc:creator><![CDATA[soban]]></dc:creator>
		<pubDate>Mon, 11 Aug 2025 11:56:18 +0000</pubDate>
				<category><![CDATA[Proxmox]]></category>
		<guid isPermaLink="false">https://soban.pl/?p=647</guid>

					<description><![CDATA[<p>Wprowadzenie Proxmox VE 9.0 (oparty na Debian 13 &#8222;Trixie&#8221;) został wydany i przynosi zaktualizowane pakiety, nowy kernel oraz ulepszoną stabilność. Ten poradnik przeprowadzi Cię przez aktualizację w miejscu z Proxmox VE 8.4.x (Debian 12 &#8222;Bookworm&#8221;) do Proxmox VE 9.0. Proces będzie zautomatyzowany przy użyciu gotowego skryptu aktualizacyjnego, który: Pobranie i uruchomienie skryptu aktualizacyjnego Możesz pobrać [&#8230;]</p>
<p>Artykuł <a href="https://soban.pl/pl/jak-zaktualizowac-proxmox-ve-8-x-do-wersji-9-0-debian-12-do-debian-13-krok-po-kroku-za-pomoca-skryptu/">Jak zaktualizować Proxmox VE 8.x do wersji 9.0 (Debian 12 do Debian 13) – krok po kroku za pomocą skryptu</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="1024" height="1024" src="https://soban.pl/wp-content/uploads/2025/08/image.png" alt="" class="wp-image-648" style="width:416px;height:auto" srcset="https://soban.pl/wp-content/uploads/2025/08/image.png 1024w, https://soban.pl/wp-content/uploads/2025/08/image-300x300.png 300w, https://soban.pl/wp-content/uploads/2025/08/image-150x150.png 150w, https://soban.pl/wp-content/uploads/2025/08/image-768x768.png 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Wprowadzenie</h2>



<p>Proxmox VE 9.0 (oparty na Debian 13 &#8222;Trixie&#8221;) został wydany i przynosi zaktualizowane pakiety, nowy kernel oraz ulepszoną stabilność. Ten poradnik przeprowadzi Cię przez <strong>aktualizację w miejscu</strong> z Proxmox VE 8.4.x (Debian 12 &#8222;Bookworm&#8221;) do Proxmox VE 9.0.</p>



<p>Proces będzie zautomatyzowany przy użyciu gotowego skryptu aktualizacyjnego, który:</p>



<ul class="wp-block-list">
<li>Sprawdza aktualną wersję</li>



<li>Uruchamia <code>pve8to9</code> w celu weryfikacji przed aktualizacją</li>



<li>Tworzy kopię zapasową źródeł APT</li>



<li>Aktualizuje repozytoria z Bookworm do Trixie</li>



<li>Wykonuje pełny dist-upgrade</li>



<li>Loguje wszystkie zmiany przed i po aktualizacji</li>
</ul>



<h2 class="wp-block-heading">Pobranie i uruchomienie skryptu aktualizacyjnego</h2>



<p>Możesz pobrać gotowy skrypt aktualizacyjny bezpośrednio z naszego serwera, nadać mu uprawnienia i uruchomić:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">wget https://soban.pl/bash/upgrade-pve8-to-9.sh -O /root/upgrade-pve8-to-9.sh
chmod +x /root/upgrade-pve8-to-9.sh
/root/upgrade-pve8-to-9.sh</pre></div>



<p>Jeśli stracisz połączenie (a to może się zdarzyć podczas aktualizacji Proxmoxa), możesz śledzić logi poleceniem:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">tail -f /root/pve-upgrade-latest.log</pre></div>



<p>Spokojnie poczekaj, aż skrypt zakończy działanie — może to potrwać.</p>



<h2 class="wp-block-heading">Pełny kod źródłowy skryptu</h2>



<p>Poniżej znajduje się pełna treść skryptu do wglądu. Zaleca się jednak pobranie najnowszej wersji z powyższego linku, aby mieć pewność, że zawiera wszystkie aktualne poprawki.</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">#!/bin/bash
# Proxmox VE 8 -&gt; 9 in-place upgrade (Debian 12 "bookworm" -&gt; Debian 13 "trixie")
# Hardened: nuke/lock Enterprise repo, move backups OUT of APT dir, ensure single no-sub,
# robust pve8to9 detection/installation, switch to trixie, non-interactive upgrade, post-boot check.
set -euo pipefail

LOG="/root/pve-upgrade-$(date +%Y%m%d-%H%M%S).log"
SINK="/etc/apt/disabled-sources"        # OUTSIDE of APT scan path
APT_BACKUP_DIR="/root/apt-sources-backup-$(date +%Y%m%d-%H%M%S)"
NO_REBOOT="${NO_REBOOT:-0}"
FORCE_UPGRADE="${FORCE_UPGRADE:-0}"
SKIP_PRECHECK="${SKIP_PRECHECK:-0}"

# Ensure sane PATH for non-interactive shells
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PATH:-}"
export DEBIAN_FRONTEND=noninteractive
export APT_LISTCHANGES_FRONTEND=none
export UCF_FORCE_CONFFOLD=1

shopt -s nullglob

msg() { echo "$*" | tee -a "$LOG"; }
die() { echo "ERROR: $*" | tee -a "$LOG"; exit 1; }
ts()  { date +%F-%H%M%S; }

sink() { # move file out of sources.list.d safely
  local f="$1" base
  [[ -e "$f" ]] || return 0
  base="$(basename "$f")"
  mkdir -p "$SINK"
  mv -f "$f" "$SINK/$base.bak.$(ts)"
}

divert_add() {
  local p="$1"
  if ! dpkg-divert --list | grep -Fq "diversion of $p"; then
    dpkg-divert --quiet --local --rename --add "$p" || true
  fi
  rm -f "$p" || true
}

cleanup_nonlist_sources() {
  mkdir -p "$SINK"
  find /etc/apt/sources.list.d -maxdepth 1 -type f \
    ! -name '*.list' ! -name '*.sources' \
    -exec mv -f {} "$SINK"/ \; || true
}

# STRICT verify: only fail on ACTIVE enterprise refs
verify_no_enterprise() {
  local bad=0
  # 1) Active lines in *.list (not commented)
  if grep -RIsn '^[[:space:]]*deb[[:space:]].*enterprise\.proxmox\.com' /etc/apt/sources.list /etc/apt/sources.list.d 2&gt;/dev/null; then
    bad=1
  fi
  # 2) Deb822 .sources that mention enterprise AND are effectively enabled
  while IFS= read -r -d '' f; do
    if grep -qi 'enterprise\.proxmox\.com' "$f"; then
      # treat missing Enabled as enabled, only "Enabled: no" is safe
      if ! grep -qi '^[[:space:]]*Enabled:[[:space:]]*no[[:space:]]*$' "$f"; then
        echo "[VERIFY] Enabled enterprise in: $f" | tee -a "$LOG"
        bad=1
      fi
    fi
  done &lt; &lt;(find /etc/apt/sources.list.d -maxdepth 1 -type f -name '*.sources' -print0 2&gt;/dev/null)
  (( bad == 0 )) || die "Enterprise repo still detected. Clean failed."
}

# Disabled deb822 stub WITHOUT enterprise domain (so greps never trip)
write_disabled_enterprise_sources() {
  cat &gt; /etc/apt/sources.list.d/pve-enterprise.sources &lt;&lt;'EOF'
Types: deb
URIs: https://example.invalid/proxmox           # placeholder to avoid enterprise domain
Suites: trixie
Components: pve-enterprise
Enabled: no
EOF
  chmod 0644 /etc/apt/sources.list.d/pve-enterprise.sources
}

# --------- FIXED: robust locator for pve8to9 + debug ----------
locate_pve8to9() {
  hash -r 2&gt;/dev/null || true
  local tool=""
  tool="$(type -P pve8to9 2&gt;/dev/null || true)"
  [[ -z "$tool" ]] &amp;&amp; tool="$(command -v pve8to9 2&gt;/dev/null || true)"
  [[ -z "$tool" &amp;&amp; -x /usr/bin/pve8to9 ]] &amp;&amp; tool="/usr/bin/pve8to9"
  [[ -z "$tool" &amp;&amp; -x /usr/sbin/pve8to9 ]] &amp;&amp; tool="/usr/sbin/pve8to9"
  [[ -z "$tool" ]] &amp;&amp; tool="$(/usr/bin/which pve8to9 2&gt;/dev/null || true)"
  if [[ -z "$tool" ]] &amp;&amp; command -v dpkg &gt;/dev/null 2&gt;&amp;1; then
    local cand
    cand="$(dpkg -L pve-manager 2&gt;/dev/null | grep -E '/pve8to9$' || true)"
    [[ -n "$cand" &amp;&amp; -x "$cand" ]] &amp;&amp; tool="$cand"
  fi
  echo "$tool"
}

run_pve8to9_precheck() {
  [[ "$SKIP_PRECHECK" == "1" ]] &amp;&amp; { msg "SKIP_PRECHECK=1 set — skipping pve8to9."; return 0; }

  msg "Running pve8to9 --full precheck..."
  msg "PATH=$PATH"
  type -a pve8to9 2&gt;&amp;1 | sed 's/^/[type] /' | tee -a "$LOG" || true
  [[ -e /usr/bin/pve8to9 ]] &amp;&amp; ls -l /usr/bin/pve8to9 | sed 's/^/[ls] /' | tee -a "$LOG" || true

  local tool; tool="$(locate_pve8to9)"

  if [[ -z "$tool" ]]; then
    msg "pve8to9 not found — attempting to ensure 'pve-manager' is installed..."
    apt-get update -y &gt;&gt; "$LOG" 2&gt;&amp;1 || true
    apt-get install -y pve-manager &gt;&gt; "$LOG" 2&gt;&amp;1 || true
    cleanup_nonlist_sources; verify_no_enterprise
    hash -r 2&gt;/dev/null || true
    tool="$(locate_pve8to9)"
  fi

  if [[ -z "$tool" ]]; then
    msg "pve8to9 still not available on this system. Continuing without precheck."
    return 0
  fi

  msg "pve8to9 found at: $tool"
  local tmp rc
  tmp="$(mktemp)"
  set +e
  "$tool" --full | tee -a "$LOG" | tee "$tmp" &gt;/dev/null
  rc=${PIPESTATUS[0]}
  set -e
  if grep -qE 'FAILURES:\s*[1-9]+' "$tmp"; then
    rm -f "$tmp"
    die "pve8to9 reported FAILURES. Check log above."
  fi
  rm -f "$tmp"
  msg "pve8to9 executed (rc=$rc). No FAILURES."
}
# ---------------------------------------------------------------

# ----- header / live log hint -----
echo "== Proxmox VE 8 -&gt; 9 upgrade started: $(date) ==" | tee -a "$LOG"
echo "$$" &gt; /run/pve8to9.pid
ln -sfn "$LOG" /root/pve-upgrade-latest.log
echo "Live log: tail -f /root/pve-upgrade-latest.log" | tee -a "$LOG"
echo "If started via nohup, also watch its file (example: /root/pve8to9.&lt;ts&gt;.nohup.log)" | tee -a "$LOG"

# 0) PRE-NUKE ENTERPRISE + move backups OUT of APT dir
msg "[PRE-NUKE] Backup APT lists and clean directory..."
mkdir -p "$APT_BACKUP_DIR"
cp -a /etc/apt/sources.list "$APT_BACKUP_DIR"/ 2&gt;/dev/null || true
cp -a /etc/apt/sources.list.d "$APT_BACKUP_DIR"/ 2&gt;/dev/null || true
cleanup_nonlist_sources

# Remove any *.sources referencing Enterprise
for s in /etc/apt/sources.list.d/*.sources; do
  [[ -f "$s" ]] || continue
  grep -qi 'enterprise\.proxmox\.com' "$s" &amp;&amp; { msg " -&gt; removing: $s"; sink "$s"; }
done
# Remove typical filenames
sink /etc/apt/sources.list.d/pve-enterprise.sources
sink /etc/apt/sources.list.d/pve-enterprise.list

# For *.list with Enterprise: comment lines or remove if Enterprise-only
for l in /etc/apt/sources.list.d/*.list; do
  [[ -f "$l" ]] || continue
  if grep -qi 'enterprise\.proxmox\.com' "$l"; then
    if awk 'BEGIN{IGNORECASE=1} /^[[:space:]]*deb/ &amp;&amp; $0 !~ /enterprise\.proxmox\.com/ {ok=1} END{exit ok?0:1}' "$l"; then
      msg " -&gt; commenting Enterprise lines in: $l"
      sed -ri 's|^\s*deb\s+https?://enterprise\.proxmox\.com|#DISABLED-BY-SCRIPT &amp;|I' "$l"
    else
      msg " -&gt; removing Enterprise-only list: $l"
      sink "$l"
    fi
  fi
done

# Comment Enterprise in main sources.list
[[ -f /etc/apt/sources.list ]] &amp;&amp; sed -ri 's|^\s*deb\s+https?://enterprise\.proxmox\.com|#DISABLED-BY-SCRIPT &amp;|I' /etc/apt/sources.list || true

# Diversions + disabled deb822 file (with example.invalid), then re-clean any .distrib/.bak
divert_add /etc/apt/sources.list.d/pve-enterprise.list
divert_add /etc/apt/sources.list.d/pve-enterprise.sources
write_disabled_enterprise_sources
cleanup_nonlist_sources
verify_no_enterprise

# 1) Sanity checks
if [[ $EUID -ne 0 ]]; then die "Run as root."; fi
if ! command -v pveversion &gt;/dev/null 2&gt;&amp;1; then die "Not a Proxmox VE host."; fi
CUR_VER_RAW="$(pveversion || true)"; msg "Current pveversion: $CUR_VER_RAW"
if ! echo "$CUR_VER_RAW" | grep -qE 'pve-manager/8\.'; then
  msg "Expected Proxmox 8.x. Detected: $CUR_VER_RAW"
  [[ "$FORCE_UPGRADE" == "1" ]] || die "Set FORCE_UPGRADE=1 to override."
fi

# BEFORE snapshot
{
  echo; echo "===== BEFORE UPGRADE ====="; date
  echo "# uname -a"; uname -a || true
  echo; echo "# pveversion"; pveversion || true
  echo; echo "# qm list"; qm list || true
  echo; echo "# pct list"; pct list || true
} &gt;&gt; "$LOG" 2&gt;&amp;1

# 2) pve8to9 precheck (robust)
run_pve8to9_precheck

# 3) Keyring + initial apt refresh
apt-get update -y &gt;&gt; "$LOG" 2&gt;&amp;1 || true
apt-get install -y proxmox-archive-keyring &gt;&gt; "$LOG" 2&gt;&amp;1 || true
verify_no_enterprise
cleanup_nonlist_sources

# 4) Switch bookworm -&gt; trixie
msg "Switching Debian repositories: bookworm -&gt; trixie ..."
sed -i 's/bookworm/trixie/g' /etc/apt/sources.list || true
find /etc/apt/sources.list.d -maxdepth 1 -type f -exec sed -i 's/bookworm/trixie/g' {} \; || true

# 5) Ensure single no-subscription entry
sed -ri '/download\.proxmox\.com\/debian\/pve.*pve-no-subscription/s/^/#DUPLICATE-BY-SCRIPT /' /etc/apt/sources.list || true
for l in /etc/apt/sources.list.d/*.list; do
  [[ -f "$l" ]] || continue
  [[ "$l" == "/etc/apt/sources.list.d/pve-no-subscription.list" ]] &amp;&amp; continue
  sed -ri '/download\.proxmox\.com\/debian\/pve.*pve-no-subscription/s/^/#DUPLICATE-BY-SCRIPT /' "$l" || true
done
cat &gt; /etc/apt/sources.list.d/pve-no-subscription.list &lt;&lt;'EOF'
deb http://download.proxmox.com/debian/pve trixie pve-no-subscription
EOF
chmod 0644 /etc/apt/sources.list.d/pve-no-subscription.list

verify_no_enterprise
cleanup_nonlist_sources

# 6) Full non-interactive upgrade
msg "Running apt-get update + non-interactive upgrade/dist-upgrade..."
TMPU="$(mktemp)"
apt-get update 2&gt;&amp;1 | tee -a "$LOG" | tee "$TMPU" &gt;/dev/null
if grep -q 'enterprise\.proxmox\.com' "$TMPU"; then rm -f "$TMPU"; die "APT tried to reach Enterprise during update."; fi
rm -f "$TMPU"

apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" upgrade -y | tee -a "$LOG"
apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" dist-upgrade -y | tee -a "$LOG"

# Second cleanup pass
cleanup_nonlist_sources

apt-get autoremove -y | tee -a "$LOG" || true
apt-get update -y &gt;&gt; "$LOG" 2&gt;&amp;1 || true

# 7) One-shot post-boot verification
POST_SH="/root/pve-postcheck.sh"
POST_SVC="/etc/systemd/system/pve-upgrade-postcheck.service"
cat &gt; "$POST_SH" &lt;&lt;'EOS'
#!/bin/bash
set -euo pipefail
LOG_FILE="/root/pve-upgrade-post-$(date +%Y%m%d-%H%M%S).log"
{
  echo "===== AFTER UPGRADE (first boot) ====="; date
  echo "# uname -a"; uname -a || true
  echo; echo "# pveversion"; pveversion || true
  echo; echo "# apt policy (trixie check)"; apt-cache policy | sed -n '1,120p' || true
} &gt;&gt; "$LOG_FILE" 2&gt;&amp;1
systemctl disable --now pve-upgrade-postcheck.service &gt;/dev/null 2&gt;&amp;1 || true
rm -f /root/pve-postcheck.sh
EOS
chmod +x "$POST_SH"
cat &gt; "$POST_SVC" &lt;&lt;'EOS'
[Unit]
Description=Proxmox upgrade post-check (one-shot)
After=multi-user.target pvedaemon.service pve-cluster.service
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/bin/bash /root/pve-postcheck.sh
[Install]
WantedBy=multi-user.target
EOS
systemctl daemon-reload
systemctl enable pve-upgrade-postcheck.service &gt;&gt; "$LOG" 2&gt;&amp;1 || true

# 8) Pre-reboot snapshot
{
  echo; echo "===== PRE-REBOOT SNAPSHOT ====="; date
  echo "# Installed pve kernels:"; dpkg -l | grep -E '^ii\s+pve-kernel' | sort -V || true
} &gt;&gt; "$LOG" 2&gt;&amp;1

msg "Upgrade phase completed. Log: $LOG"
if [[ "$NO_REBOOT" == "1" ]]; then
  msg "NO_REBOOT=1 set — skipping reboot. Please reboot manually."
else
  msg "Rebooting now to complete the upgrade..."
  sleep 3
  reboot
fi</pre></div>



<h2 class="wp-block-heading">Weryfikacja po aktualizacji</h2>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">pveversion</pre></div>



<p>Oczekiwany wynik powinien wyglądać tak:</p>



<p>pve-manager/9.x.x/xxxxxxxx (running kernel: 6.x.x-x-pve)<br><br>Sprawdź wersję uruchomionego jądra:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">uname -a</pre></div>



<p>Przejrzyj log z aktualizacji, aby upewnić się, że nie wystąpiły błędy:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">less /root/pve-upgrade-*.log</pre></div>



<p>Jeśli użyłeś usługi post-check utworzonej przez skrypt, możesz zobaczyć jej wyniki:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">less /root/pve-upgrade-post-*.log</pre></div>
<p>Artykuł <a href="https://soban.pl/pl/jak-zaktualizowac-proxmox-ve-8-x-do-wersji-9-0-debian-12-do-debian-13-krok-po-kroku-za-pomoca-skryptu/">Jak zaktualizować Proxmox VE 8.x do wersji 9.0 (Debian 12 do Debian 13) – krok po kroku za pomocą skryptu</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Dynamiczne nazwy zakładek w Tmuxie z SSH i hostname</title>
		<link>https://soban.pl/pl/dynamiczne-nazwy-zakladek-w-tmuxie-z-ssh-i-hostname/</link>
		
		<dc:creator><![CDATA[soban]]></dc:creator>
		<pubDate>Tue, 15 Apr 2025 14:57:06 +0000</pubDate>
				<category><![CDATA[Bash]]></category>
		<category><![CDATA[tmux]]></category>
		<guid isPermaLink="false">https://soban.pl/?p=633</guid>

					<description><![CDATA[<p>Dynamiczne nazwy zakładek w Tmuxie z SSH i hostname Chcesz, aby Twoje zakładki (okna) w Tmuxie automatycznie pokazywały hostname serwera, do którego się logujesz przez SSH? A po wylogowaniu wracały do nazwy lokalnego hosta? Ten poradnik pokaże Ci, jak to skonfigurować krok po kroku. 1. Konfiguracja Tmux – ~/.tmux.conf W pliku konfiguracyjnym Tmuxa ustaw domyślną [&#8230;]</p>
<p>Artykuł <a href="https://soban.pl/pl/dynamiczne-nazwy-zakladek-w-tmuxie-z-ssh-i-hostname/">Dynamiczne nazwy zakładek w Tmuxie z SSH i hostname</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="1024" height="1024" src="https://soban.pl/wp-content/uploads/2025/04/image-2.png" alt="" class="wp-image-634" style="width:454px;height:auto" srcset="https://soban.pl/wp-content/uploads/2025/04/image-2.png 1024w, https://soban.pl/wp-content/uploads/2025/04/image-2-300x300.png 300w, https://soban.pl/wp-content/uploads/2025/04/image-2-150x150.png 150w, https://soban.pl/wp-content/uploads/2025/04/image-2-768x768.png 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><br>Dynamiczne nazwy zakładek w Tmuxie z SSH i hostname</p>



<p>Chcesz, aby Twoje zakładki (okna) w Tmuxie automatycznie pokazywały hostname serwera, do którego się logujesz przez SSH? A po wylogowaniu wracały do nazwy lokalnego hosta? Ten poradnik pokaże Ci, jak to skonfigurować krok po kroku.</p>



<h2 class="wp-block-heading">1. Konfiguracja Tmux – ~/.tmux.conf</h2>



<p>W pliku konfiguracyjnym Tmuxa ustaw domyślną komendę startową na specjalny plik Bash (<code>.bash_tmux</code>), który załatwi całą magię.</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">set-option -g default-command 'bash --rcfile ~/.bash_tmux'</pre></div>



<h2 class="wp-block-heading">2. Skrypt startowy Bash – ~/.bash_tmux</h2>



<p>Ten plik wykonuje się przy każdym starcie okna Tmux. Ustawia nazwę okna na hostname oraz nadpisuje polecenie <code>ssh</code>, aby aktualizowało zakładkę przy połączeniu i po rozłączeniu.</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">#!/bin/bash
# ~/.bash_tmux
# Custom Bash init file for Tmux sessions with dynamic tab naming

# Override the default ssh command to dynamically rename the Tmux window
ssh() {
  if [ -n "$TMUX" ]; then
    # Loop through arguments to find the target host (first non-flag argument)
    for arg in "$@"; do
      if [[ "$arg" != -* ]]; then
        if [[ "$arg" == *@* ]]; then
          host="${arg#*@}"  # extract host from user@host
        else
          host="$arg"
        fi
        break
      fi
    done

    # Strip any trailing junk or whitespace
    host="$(echo "$host" | cut -d' ' -f1)"

    # Rename the Tmux window to the SSH target
    [ -n "$host" ] &amp;&amp; tmux rename-window "$host"

    # Save the local hostname to restore later
    local_host="$(hostname -s)"

    # Run the actual SSH command
    command ssh "$@"

    # Restore the original window name after logout
    tmux rename-window "$local_host"
  else
    # Not in Tmux — just run ssh normally
    command ssh "$@"
  fi
}

# Load the user's regular bash configuration
source ~/.bashrc

# On shell start, if in Tmux, set the window name to the current hostname
if [ -n "$TMUX" ]; then
  tmux rename-window "$(hostname -s)"
fi</pre></div>



<h2 class="wp-block-heading">3. Przeładowanie konfiguracji Tmux bez restartu</h2>



<p>Aby zastosować zmiany bez restartowania całej sesji Tmux, użyj następującego polecenia:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">tmux source-file ~/.tmux.conf</pre></div>



<p>Dodatkowo możesz przeładować bieżącą powłokę z <code>.bash_tmux</code> ręcznie:</p>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">exec bash --rcfile ~/.bash_tmux</pre></div>



<h2 class="wp-block-heading">4. Efekt końcowy</h2>



<ul class="wp-block-list">
<li>Nowe okno Tmux ma automatycznie nazwę lokalnego hosta</li>



<li>Po połączeniu przez SSH — zakładka zmienia się na nazwę zdalnego hosta</li>



<li>Po wylogowaniu — zakładka wraca do lokalnego hostname</li>
</ul>



<p>Prosto, czytelnie i mega wygodnie — idealne dla adminów, devopsów i fanów porządku w Tmuxie 💪</p>



<p></p>
<p>Artykuł <a href="https://soban.pl/pl/dynamiczne-nazwy-zakladek-w-tmuxie-z-ssh-i-hostname/">Dynamiczne nazwy zakładek w Tmuxie z SSH i hostname</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Najważniejsze polecenia Linuxa, które każdy użytkownik powinien znać</title>
		<link>https://soban.pl/pl/najwazniejsze-polecenia-linuxa-ktore-kazdy-uzytkownik-powinien-znac/</link>
		
		<dc:creator><![CDATA[soban]]></dc:creator>
		<pubDate>Thu, 20 Feb 2025 10:32:22 +0000</pubDate>
				<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">https://soban.pl/?p=615</guid>

					<description><![CDATA[<p>System Linux to potężne narzędzie, które oferuje użytkownikom ogromną elastyczność i kontrolę nad ich środowiskiem pracy. Jednak aby w pełni wykorzystać jego potencjał, warto poznać kluczowe polecenia, które są niezbędne zarówno dla początkujących, jak i zaawansowanych użytkowników. W tym artykule przedstawimy i omówimy najważniejsze polecenia w systemie Linux, które każdy użytkownik powinien znać. 1. Podstawowe [&#8230;]</p>
<p>Artykuł <a href="https://soban.pl/pl/najwazniejsze-polecenia-linuxa-ktore-kazdy-uzytkownik-powinien-znac/">Najważniejsze polecenia Linuxa, które każdy użytkownik powinien znać</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1017" height="1024" src="https://soban.pl/wp-content/uploads/2025/02/image-4-1017x1024.png" alt="" class="wp-image-625" style="width:511px;height:auto" srcset="https://soban.pl/wp-content/uploads/2025/02/image-4-1017x1024.png 1017w, https://soban.pl/wp-content/uploads/2025/02/image-4-298x300.png 298w, https://soban.pl/wp-content/uploads/2025/02/image-4-150x150.png 150w, https://soban.pl/wp-content/uploads/2025/02/image-4-768x774.png 768w, https://soban.pl/wp-content/uploads/2025/02/image-4.png 1105w" sizes="auto, (max-width: 1017px) 100vw, 1017px" /></figure>



<p>System Linux to potężne narzędzie, które oferuje użytkownikom ogromną elastyczność i kontrolę nad ich środowiskiem pracy. Jednak aby w pełni wykorzystać jego potencjał, warto poznać kluczowe polecenia, które są niezbędne zarówno dla początkujących, jak i zaawansowanych użytkowników. W tym artykule przedstawimy i omówimy najważniejsze polecenia w systemie Linux, które każdy użytkownik powinien znać.</p>



<h2 class="wp-block-heading">1. Podstawowe polecenia nawigacyjne</h2>



<ul class="wp-block-list">
<li><code>pwd</code> &#8211; Wyświetla bieżącą ścieżkę katalogu, w którym się znajdujesz:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">pwd</pre></div>



<li><code>ls</code> &#8211; Listuje zawartość katalogu. Można użyć opcji <code>-l</code> dla szczegółowego widoku lub <code>-a</code> aby pokazać ukryte pliki:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">ls -a</pre></div>



<li><code>cd</code> &#8211; Zmienia katalog. Na przykład <code>cd /home/user</code> przeniesie Cię do katalogu <code>/home/user</code>:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">cd ~</pre></div>



<li><code>mkdir</code> &#8211; Tworzy nowy katalog:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">mkdir projekty</pre></div>



<li><code>rmdir</code> &#8211; Usuwa pusty katalog:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">rmdir stare_pliki</pre></div>
</ul>



<h2 class="wp-block-heading">2. Zarządzanie plikami</h2>



<ul class="wp-block-list">
<li><code>cp</code> &#8211; Kopiuje pliki lub katalogi:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">cp dokument.txt nowy_katalog/</pre></div>



<li><code>mv</code> &#8211; Przenosi lub zmienia nazwę plików/katalogów:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">mv plik.txt /home/user/nowy_katalog/</pre></div>



<li><code>rm</code> &#8211; Usuwa pliki lub katalogi. Użyj opcji <code>-r</code> aby usunąć katalog z zawartością:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">rm -r stare_dane</pre></div>



<li><code>touch</code> &#8211; Tworzy pusty plik lub aktualizuje czas modyfikacji istniejącego pliku:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">touch raport.txt</pre></div>
</ul>



<h2 class="wp-block-heading">3. Zarządzanie procesami</h2>



<ul class="wp-block-list">
<li><code>ps</code> &#8211; Wyświetla aktualnie uruchomione procesy. Użyj opcji <code>-aux</code> aby zobaczyć wszystkie procesy:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">ps -aux</pre></div>



<li><code>top</code> &#8211; Wyświetla dynamiczną listę procesów w czasie rzeczywistym:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">top</pre></div>



<li><code>kill</code> &#8211; Zatrzymuje proces o podanym ID:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">kill 1234</pre></div>



<li><code>bg</code> i <code>fg</code> &#8211; Zarządzanie procesami w tle i na pierwszym planie:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">fg</pre></div>
</ul>



<h2 class="wp-block-heading">4. Zarządzanie użytkownikami i uprawnieniami</h2>



<ul class="wp-block-list">
<li><code>sudo</code> &#8211; Pozwala na wykonanie polecenia z uprawnieniami administratora:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">sudo apt update</pre></div>



<li><code>chmod</code> &#8211; Zmienia uprawnienia do plików/katalogów:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">chmod 755 skrypt.sh</pre></div>



<li><code>chown</code> &#8211; Zmienia właściciela pliku/katalogu:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">chown admin:admin plik.txt</pre></div>



<li><code>useradd</code> i <code>userdel</code> &#8211; Dodaje i usuwa użytkowników:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">useradd janek</pre></div>
</ul>



<h2 class="wp-block-heading">5. Sieć i komunikacja</h2>



<ul class="wp-block-list">
<li><code>ping</code> &#8211; Sprawdza połączenie z innym hostem:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">ping 192.168.1.1</pre></div>



<li><code>ifconfig</code> &#8211; Wyświetla informacje o interfejsach sieciowych:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">ifconfig</pre></div>



<li><code>ssh</code> &#8211; Łączy się zdalnie z innym komputerem:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">ssh user@192.168.1.2</pre></div>



<li><code>scp</code> &#8211; Kopiuje pliki przez SSH:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">scp plik.txt user@host:/home/user/</pre></div>
</ul>



<h2 class="wp-block-heading">6. Przykłady użycia poleceń</h2>



<p>Poniżej znajduje się przykład użycia kilku omówionych poleceń:</p>



<ul class="wp-block-list">
<li><code>chmod</code> &#8211; Zmienia uprawnienia do plików/katalogów:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">chmod 755 skrypt.sh</pre></div>



<li><code>chown</code> &#8211; Zmienia właściciela pliku/katalogu:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">chown admin:developers logi.txt</pre></div>



<li><code>useradd</code> i <code>userdel</code> &#8211; Dodaje i usuwa użytkowników:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">useradd janek</pre></div>
</ul>



<h2 class="wp-block-heading">7. Zarządzanie dyskami i systemem plików</h2>



<ul class="wp-block-list">
<li><code>df</code> &#8211; Wyświetla informacje o dostępnej przestrzeni na dyskach:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">df -h</pre></div>



<li><code>du</code> &#8211; Pokazuje rozmiar plików i katalogów:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">du -sh documents</pre></div>



<li><code>mount</code> &#8211; Montuje system plików:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">mount /dev/sdb1 /mnt/external</pre></div>



<li><code>umount</code> &#8211; Odmontowuje system plików:</li>



<div class="wp-block-urvanov-syntax-highlighter-code-block"><pre class="urvanov-syntax-highlighter-plain-tag">umount /mnt/external</pre></div>
</ul>



<h2 class="wp-block-heading">8. Wyszukiwanie plików</h2>



<ul class="wp-block-list">
<li><code>find</code> &#8211; Wyszukuje pliki w systemie:</li>



<li><code>locate</code> &#8211; Szybkie wyszukiwanie plików w systemie:</li>



<li><code>grep</code> &#8211; Wyszukuje wzorce w plikach:</li>



<li><code>which</code> &#8211; Znajduje pełną ścieżkę do wykonywalnego pliku:</li>
</ul>



<h2 class="wp-block-heading">9. Komunikacja z systemem</h2>



<ul class="wp-block-list">
<li><code>echo</code> &#8211; Wyświetla tekst na ekranie:</li>



<li><code>cat</code> &#8211; Wyświetla zawartość pliku:</li>



<li><code>more</code> &#8211; Wyświetla zawartość pliku strona po stronie:</li>



<li><code>less</code> &#8211; Zawiera funkcje podobne do more, ale oferuje więcej opcji nawigacji:</li>



<li><code>man</code> &#8211; Wyświetla podręcznik użytkownika dla polecenia:</li>
</ul>



<h2 class="wp-block-heading">10. Praca z archiwami</h2>



<ul class="wp-block-list">
<li><code>tar</code> &#8211; Tworzy archiwum lub rozpakowuje je:</li>



<li><code>zip</code> &#8211; Tworzy archiwum ZIP:</li>



<li><code>unzip</code> &#8211; Rozpakowuje pliki ZIP:</li>



<li><code>tar -xvzf</code> &#8211; Rozpakowuje archiwum TAR.GZ:</li>



<li><code>gzip</code> &#8211; Kompresuje pliki w formacie .gz:</li>



<li><code>gunzip</code> &#8211; Rozpakowuje pliki .gz:</li>
</ul>



<h2 class="wp-block-heading">11. Monitorowanie systemu</h2>



<ul class="wp-block-list">
<li><code>uptime</code> &#8211; Wyświetla czas działania systemu oraz obciążenie:</li>



<li><code>dmesg</code> &#8211; Wyświetla komunikaty systemowe związane z rozruchem i sprzętem:</li>



<li><code>iostat</code> &#8211; Pokazuje statystyki wejścia/wyjścia systemu:</li>



<li><code>free</code> &#8211; Pokazuje informacje o pamięci RAM:</li>



<li><code>netstat</code> &#8211; Wyświetla informacje o połączeniach sieciowych:</li>



<li><code>ss</code> &#8211; Nowoczesna wersja netstat, służy do monitorowania połączeń sieciowych:</li>
</ul>



<h2 class="wp-block-heading">12. Praca z logami systemowymi</h2>



<ul class="wp-block-list">
<li><code>journalctl</code> &#8211; Przegląda logi systemowe:</li>



<li><code>tail</code> &#8211; Wyświetla ostatnie linie pliku:</li>



<li><code>logrotate</code> &#8211; Automatycznie zarządza logami:</li>
</ul>



<h2 class="wp-block-heading">13. Zaawansowane operacje na plikach</h2>



<ul class="wp-block-list">
<li><code>ln</code> &#8211; Tworzy dowiązanie do pliku:</li>



<li><code>xargs</code> &#8211; Przesyła argumenty z wejścia do innych poleceń:</li>



<li><code>chmod</code> &#8211; Zmienia uprawnienia do plików/katalogów:</li>



<li><code>chattr</code> &#8211; Zmienia atrybuty plików:</li>
</ul>


<p>System Linux oferuje szeroki zestaw poleceń, które pozwalają na pełną kontrolę nad komputerem. Kluczowe polecenia, jak <code>ls</code>, <code>cd</code>, <code>cp</code>, czy <code>rm</code>, są używane na co dzień do nawigacji po systemie plików, zarządzania plikami oraz katalogami. Aby skutecznie opanować te komendy, najlepiej zacząć od tych, które są najbardziej przydatne w codziennej pracy. Przykładowo, polecenia do nawigacji po katalogach i zarządzania plikami są fundamentalne i wymagają praktyki, aby stały się intuicyjne. Inne polecenia, takie jak <code>ps</code> do monitorowania procesów, <code>ping</code> do testowania połączeń sieciowych, czy <code>chmod</code> do zmiany uprawnień, również warto poznać, aby móc w pełni wykorzystać moc systemu Linux.</p>
<p><!-- /wp:post-content --></p>
<p><!-- wp:paragraph --></p>
<p>Aby uczyć się skutecznie, warto zacząć od eksperymentowania z poleceniami w praktyce. Tworzenie plików, katalogów, kopiowanie i usuwanie danych pozwala na zapoznanie się z ich działaniem. Z czasem warto zacząć łączyć różne polecenia, by rozwiązywać bardziej zaawansowane problemy, jak monitorowanie procesów, zarządzanie użytkownikami czy praca z logami systemowymi. Można także korzystać z dokumentacji, np. <code>man</code> lub stron internetowych, aby zgłębiać szczegóły każdego polecenia i jego opcji.</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p>Pamiętaj, że regularne korzystanie z terminala pozwala na naukę nawyków, które sprawią, że obsługa systemu Linux stanie się bardziej naturalna. Częste korzystanie z poleceń, rozwiązywanie problemów oraz eksperymentowanie z nowymi komendami to najlepszy sposób na opanowanie systemu i wykorzystywanie go w pełni.</p>
<p><!-- /wp:paragraph --></p>
<p><!-- wp:paragraph --></p>
<p>Linux to naprawdę potężne narzędzie, które daje ogromną kontrolę nad systemem&#8230; ale pamiętaj, nie eksperymentuj na produkcji! W końcu, eksperymentowanie na serwerze produkcyjnym to trochę jak gra w rosyjską ruletkę — tylko że z większymi konsekwencjami. Jeśli chcesz poczuć się jak prawdziwy Linuxowy magik, zawsze testuj swoje komendy na środowisku deweloperskim. Tylko wtedy będziesz w stanie uczyć się na błędach, zamiast szukać przyczyny zniknięcia kilku gigabajtów danych. A jeśli nie wiesz, co robisz, po prostu wezwij swoją niezawodną broń: <code>man</code>!</p>
<p><!-- /wp:paragraph --></p><p>Artykuł <a href="https://soban.pl/pl/najwazniejsze-polecenia-linuxa-ktore-kazdy-uzytkownik-powinien-znac/">Najważniejsze polecenia Linuxa, które każdy użytkownik powinien znać</a> pochodzi z serwisu <a href="https://soban.pl/pl">soban</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
