Compare commits
5 Commits
2025.05.20
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
359d62df58 | ||
|
466d510264 | ||
|
a0a98c0014 | ||
|
f9be7b0c10 | ||
|
861bdcd686 |
101
blog/2025-05-21-make-one-proxmox-node-to-wol-another/index.md
Normal file
101
blog/2025-05-21-make-one-proxmox-node-to-wol-another/index.md
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
---
|
||||||
|
slug: make-one-proxmox-node-to-wol-another
|
||||||
|
title: "Make one Proxmox node to wake-on-lan another"
|
||||||
|
tags: [self-hosting, homelab, Proxmox, WOL]
|
||||||
|
image: /img/homelab.png
|
||||||
|
---
|
||||||
|
Nothing is eternal, especially the relevance of documentation. I think help.ubuntu.com is an absolute winner, holding the largest number of outdated and irrelevant pages. But that's not a topic for today's post.
|
||||||
|
One of my Proxmox cluster nodes can't power itself on after the outage. But it supports wake-on-LAN, so I decided that another node could power it on. And the simplicity of this task was overrated by me.
|
||||||
|
|
||||||
|
<!-- truncate -->
|
||||||
|
|
||||||
|
:::warning
|
||||||
|
|
||||||
|
Wake on LAN doesn't work across VLANs. Magic packets could be sent and received only inside a single subnet.
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
|
## The victim
|
||||||
|
|
||||||
|
First of all, even after enabling "Wake up on PCI event" or something in BIOS it was not working because WoL was still disabled on a software level. It can be checked with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ethtool enp1s0
|
||||||
|
```
|
||||||
|
|
||||||
|
Where `enp1s0` is a physical network interface of a Proxmox node, not a bridge.
|
||||||
|
|
||||||
|
There should be `Wake-on:` setting among others. In my case it was `Wake-on: d`, which means that wake-on-LAN is disabled, according to `ethtool` documentation:
|
||||||
|
|
||||||
|
```
|
||||||
|
p Wake on phy activity
|
||||||
|
u Wake on unicast messages
|
||||||
|
m Wake on multicast messages
|
||||||
|
b Wake on broadcast messages
|
||||||
|
a Wake on ARP
|
||||||
|
g Wake on MagicPacket(tm)
|
||||||
|
s Enable SecureOn(tm) password for MagicPacket(tm)
|
||||||
|
d Disable (wake on nothing). This option clears all previous
|
||||||
|
options.
|
||||||
|
```
|
||||||
|
|
||||||
|
We need to set it to wake by the MagicPacket(tm). We need to create a config file for this to be enabled on system start. But first we need to:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ip link show enp1s0
|
||||||
|
```
|
||||||
|
|
||||||
|
and write down our network device MAC address. Then create a file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nano /etc/systemd/network/90-wakeonlan.link
|
||||||
|
```
|
||||||
|
|
||||||
|
with the next content:
|
||||||
|
|
||||||
|
```
|
||||||
|
[Match]
|
||||||
|
MACAddress=<mac-address-here>
|
||||||
|
|
||||||
|
[Link]
|
||||||
|
NamePolicy=kernel database onboard slot path
|
||||||
|
MACAddressPolicy=persistent
|
||||||
|
WakeOnLan=magic
|
||||||
|
```
|
||||||
|
|
||||||
|
After that we need to reboot and check WOL status again:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ethtool enp1s0
|
||||||
|
```
|
||||||
|
|
||||||
|
Now `Wake-on` should be set to `g`.
|
||||||
|
|
||||||
|
## The one who bothering
|
||||||
|
|
||||||
|
On another node we need to install an util that will be sending a magic packet:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
apt update
|
||||||
|
apt install etherwake
|
||||||
|
```
|
||||||
|
|
||||||
|
Now we can power the victim off and try to wake it with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
etherwake -i vmbr0 <mac_address>
|
||||||
|
```
|
||||||
|
|
||||||
|
Where `vmbr0` is a bridge network interface of current Proxmox node, and `<mac_address>` is a MAC address of the victim's physical network interface.
|
||||||
|
|
||||||
|
If it works, we can now add a cron job to wake our victim upon current node startup, adding some delay to make sure the network is ready:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
crontab -e
|
||||||
|
```
|
||||||
|
|
||||||
|
Cron job line to add:
|
||||||
|
|
||||||
|
```
|
||||||
|
@reboot sleep 30s && /usr/sbin/etherwake -i vmbr0 <mac_address>
|
||||||
|
```
|
0
docs/homelab/Services/outline.md
Normal file
0
docs/homelab/Services/outline.md
Normal file
@ -1,9 +1,29 @@
|
|||||||
---
|
---
|
||||||
sidebar_position: 1
|
sidebar_position: 1
|
||||||
|
title: Overview
|
||||||
---
|
---
|
||||||
|
|
||||||
# What is it?
|
## What is it?
|
||||||
|
|
||||||
This is my project of publicly available documentation of my home servers and services.
|
This is my project of publicly available documentation of my home servers and self-hosted services.
|
||||||
|
|
||||||
Working on it...
|
## Network
|
||||||
|
|
||||||
|
The gate to my HomeLab is a **UniFi Cloud Gateway Ultra**. It is connected to a **1 Gbps** fiber optic from my ISP and manages **3 static WAN IP** addresses.
|
||||||
|
|
||||||
|
The local network is separated into **four VLANs**.
|
||||||
|
|
||||||
|
The gateway is also a DNS server for all local network and VPN clients.
|
||||||
|
|
||||||
|
WiFi network is delivered by **two UniFi U6+** access points powered with the **Switch Lite 8 PoE**.
|
||||||
|
|
||||||
|
[More on network](network.md)
|
||||||
|
|
||||||
|
## Servers
|
||||||
|
My family home cloud is provided by the **Synology DS423+**. It is for photos and documents hosting and sharing.
|
||||||
|
|
||||||
|
I also have a **DIY NAS with TrueNAS Community Edition** on it that hosts most of the services for personal and family use, that are not from Synology.
|
||||||
|
|
||||||
|
The third one is the **Asus PN42** min PC with an Intel N100 CPU with the **Proxomox VE** on it. It hosts public services, like this website, my Gitea instance, and others.
|
||||||
|
|
||||||
|
I also have a mighty **Home Assistant Blue** with... well **Home Assistant** on it. It does not depend on other servers and has a separate Cloudflare tunnel to it from the outside to be available even when all other servers fail.
|
||||||
|
84
docs/homelab/network.md
Normal file
84
docs/homelab/network.md
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
---
|
||||||
|
title: Network
|
||||||
|
---
|
||||||
|
## WAN
|
||||||
|
|
||||||
|
### Port forwarding
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
---
|
||||||
|
config:
|
||||||
|
look: handDrawn
|
||||||
|
theme: neutral
|
||||||
|
---
|
||||||
|
flowchart LR
|
||||||
|
W8[WAN IP *8]
|
||||||
|
W9[WAN IP *9]
|
||||||
|
W0[WAN IP *0]
|
||||||
|
montgomery("`Synology NAS
|
||||||
|
_DSM Web UI, Hyper Backup Vault, Drive Server_`")
|
||||||
|
plex(Plex external access)
|
||||||
|
ingress50("`ingress-50
|
||||||
|
_Zoraxy_`")
|
||||||
|
ingress1("`ingress-1
|
||||||
|
_Zoraxy_`")
|
||||||
|
WAN1 --> W8
|
||||||
|
WAN1 --> W9
|
||||||
|
WAN1 --> W0
|
||||||
|
W8 --> montgomery
|
||||||
|
W8 --> plex
|
||||||
|
W8 --> qbt(qBittorrent)
|
||||||
|
W9 --> gitssh(Gitea SSH)
|
||||||
|
W9 --> ingress50 --> pub(Public services)
|
||||||
|
W0 --> ingress1 --> per(Personal services)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Firewall rules
|
||||||
|
In addition to default rules.
|
||||||
|
|
||||||
|
| Name | Action | Source Zone | Destination Zone |
|
||||||
|
|-------------------------- | ------ | ------------- | ---------------- |
|
||||||
|
| Allow UniFi remote access | Allow | External | Gateway |
|
||||||
|
|
||||||
|
## Local network
|
||||||
|
### VLANs
|
||||||
|
| Name | Subnet | Description | Isolate network |
|
||||||
|
|------------ | ----------------- | ------------------------------------------------------------- | --------------- |
|
||||||
|
| **Default** | _192.168.1.0/24_ | Default local network for laptops, family phones and tablets | No |
|
||||||
|
| **Pub** | _192.168.50.0/24_ | An isolated VLAN for public services | No |
|
||||||
|
| **Guest** | _192.168.5.0/24_ | An isolated VLAN for guest WiFi access | No |
|
||||||
|
| **IoT** | _192.168.6.0/24_ | An isolated VLAN for connected home appliance | No |
|
||||||
|
|
||||||
|
- Device Isolation is disabled for all networks
|
||||||
|
|
||||||
|
### Firewall zones
|
||||||
|
| Name | Built in | Networks / Interfaces |
|
||||||
|
|---------------- | -------- | ------------------------------------------- |
|
||||||
|
| Internal | âś… | [`Default`](#vlans) |
|
||||||
|
| External | âś… | [`Primary (WAN1)`](#wan) `Secondary (WAN2)` |
|
||||||
|
| Gateway | âś… | - |
|
||||||
|
| VPN | âś… | [`Hearthstone`](#vpn) [`VPS`](#vpn) |
|
||||||
|
| Hotspot | âś… | [`Guest`](#vlans) |
|
||||||
|
| DMZ | âś… | - |
|
||||||
|
| VLAN 50 | ❌ | [`Pub`](#vlans) |
|
||||||
|
| VLAN 6 | ❌ | [`IoT`](#vlans) |
|
||||||
|
|
||||||
|
### Zones access rules
|
||||||
|
Additional Firewall rules allowing or blocking zone-to-zone or subnet-to-subnet communications.
|
||||||
|
|
||||||
|
| Source Zone | Destination Zone | Source | Destination | Action | Description |
|
||||||
|
|-------------- | ---------------- | --------------------- | --------------------------- | ------------------ | ---------------------------------------------------------------------------------- |
|
||||||
|
| Internal | VLAN 50 | All | All | Allow with return | Allow all traffic from [`Default`](#vlans) network to [`Pub`](#vlans) |
|
||||||
|
| Internal | VLAN 6 | All | All | Allow with return | Allow all traffic from [`Default`](#vlans) network to [`IoT`](#vlans) |
|
||||||
|
| VPN | Internal | [VPS subnet](#vpn) | All | Allow only return | Allow return traffic from [`VPS`](#vpn) subnet to [`Default`](#vlans) |
|
||||||
|
| VPN | Internal | [VPS subnet](#vpn) | All | Block | Block [`VPS`](#vpn) VPN clients from accessing the [`Default`](#vlans) network |
|
||||||
|
| VPN | Hotspot | [VPS subnet](#vpn) | All | Block | Block [`VPS`](#vpn) VPN clients from accessing the [`Guest`](#vlans) network |
|
||||||
|
| VPN | DMZ | [VPS subnet](#vpn) | All | Block | Block [`VPS`](#vpn) VPN clients from accessing the [`DMZ`](#firewall-zones) zone |
|
||||||
|
| VPN | VLAN 50 | All | [Hearthstone](#vpn) | Allow all | Allow [`Hearthstone`](#vpn) VPN clients access to [`Pub`](#vlans) network |
|
||||||
|
| VPN | VLAN 6 (IoT) | All | [Hearthstone](#vpn) | Allow all | Block [`Hearthstone`](#vpn) VPN clients access to [`IoT`](#vlans) network |
|
||||||
|
| VLAN 50 | VLAN 50 | All | All | Allow all | Allow [`Pub`](#vlans) network clients accessing each other |
|
||||||
|
|
||||||
|
## VPN
|
||||||
|
There are two Wireguard servers configured:
|
||||||
|
1. **Hearthstone**. Subnet _192.168.3.0/24_. For external access to all local networks.
|
||||||
|
1. **VPS**. Subnet _192.168.4.0/24_. For accessing VPS servers as local network devices.
|
@ -36,6 +36,12 @@ const config = {
|
|||||||
locales: ['en'],
|
locales: ['en'],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
markdown: {
|
||||||
|
mermaid: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
themes: ['@docusaurus/theme-mermaid'],
|
||||||
|
|
||||||
scripts: [
|
scripts: [
|
||||||
{
|
{
|
||||||
src: 'https://plausible.nicelycomposed.codes/js/script.outbound-links.js',
|
src: 'https://plausible.nicelycomposed.codes/js/script.outbound-links.js',
|
||||||
@ -56,6 +62,9 @@ const config = {
|
|||||||
showReadingTime: true,
|
showReadingTime: true,
|
||||||
feedOptions: {
|
feedOptions: {
|
||||||
type: ['rss', 'atom'],
|
type: ['rss', 'atom'],
|
||||||
|
title: "Yehor Vialov's Blog",
|
||||||
|
description: 'Some notes, interesting things and projects',
|
||||||
|
copyright: 'Copyright © ${new Date().getFullYear()} Yehor Vialov',
|
||||||
xslt: true,
|
xslt: true,
|
||||||
},
|
},
|
||||||
blogSidebarTitle: 'Timeline',
|
blogSidebarTitle: 'Timeline',
|
||||||
@ -112,6 +121,14 @@ const config = {
|
|||||||
label: 'Blog',
|
label: 'Blog',
|
||||||
to: '/blog',
|
to: '/blog',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'Blog RSS feed',
|
||||||
|
to: 'pathname:///blog/rss.xml',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Blog Atom feed',
|
||||||
|
to: 'pathname:///blog/atom.xml',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/core": "3.7.0",
|
"@docusaurus/core": "3.7.0",
|
||||||
"@docusaurus/preset-classic": "3.7.0",
|
"@docusaurus/preset-classic": "3.7.0",
|
||||||
|
"@docusaurus/theme-mermaid": "^3.7.0",
|
||||||
"@mdx-js/react": "^3.0.0",
|
"@mdx-js/react": "^3.0.0",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.0.0",
|
||||||
"prism-react-renderer": "^2.3.0",
|
"prism-react-renderer": "^2.3.0",
|
||||||
@ -41,4 +42,4 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0"
|
"node": ">=18.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,8 @@
|
|||||||
const sidebars = {
|
const sidebars = {
|
||||||
|
|
||||||
homelabSidebar: [{
|
homelabSidebar: [{
|
||||||
type: 'doc',
|
type: 'autogenerated',
|
||||||
id: 'homelab/index',
|
dirName: 'homelab',
|
||||||
label: 'HomeLab',
|
|
||||||
},],
|
},],
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,16 +3,6 @@ import Heading from '@theme/Heading';
|
|||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
|
|
||||||
const FeatureList = [
|
const FeatureList = [
|
||||||
{
|
|
||||||
title: 'HomeLab Documented',
|
|
||||||
link: 'docs/homelab',
|
|
||||||
Svg: require('@site/static/img/homelab.svg').default,
|
|
||||||
description: (
|
|
||||||
<>
|
|
||||||
Here I'm trying my best in documenting my home servers and services.
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: 'Blog',
|
title: 'Blog',
|
||||||
link: 'blog',
|
link: 'blog',
|
||||||
@ -23,7 +13,16 @@ const FeatureList = [
|
|||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'HomeLab Documented',
|
||||||
|
link: 'docs/homelab',
|
||||||
|
Svg: require('@site/static/img/homelab.svg').default,
|
||||||
|
description: (
|
||||||
|
<>
|
||||||
|
Here I'm trying my best in documenting my home servers and self-hosted services.
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
function Feature({ Svg, title, link, description }) {
|
function Feature({ Svg, title, link, description }) {
|
||||||
|
15
src/pages/deleted-post.md
Normal file
15
src/pages/deleted-post.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
title: This post was removed
|
||||||
|
description: A message about removed content
|
||||||
|
hide_table_of_contents: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# You probably got here visiting a link somewhere on the internet
|
||||||
|
|
||||||
|
Sorry to say, but this post was removed because of one of the reasons (or because of all of them):
|
||||||
|
- It was critically outdated
|
||||||
|
- It was misleading
|
||||||
|
- It was stupid
|
||||||
|
- It has no historical value
|
||||||
|
|
||||||
|
You can check my [other blog posts](/blog) or start from the [home page](/).
|
@ -13,9 +13,9 @@ function HomepageHeader() {
|
|||||||
<header className={clsx('hero hero--primary', styles.heroBanner)}>
|
<header className={clsx('hero hero--primary', styles.heroBanner)}>
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<Heading as="h1" className="hero__title">
|
<Heading as="h1" className="hero__title">
|
||||||
{siteConfig.title}
|
Yehor Vialov
|
||||||
</Heading>
|
</Heading>
|
||||||
<p className="hero__subtitle">{siteConfig.tagline}</p>
|
<p className="hero__subtitle">Public Profiles</p>
|
||||||
<div className={styles.buttons}>
|
<div className={styles.buttons}>
|
||||||
<Link
|
<Link
|
||||||
className="button button--secondary button--lg"
|
className="button button--secondary button--lg"
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
---
|
|
||||||
title: Markdown page example
|
|
||||||
---
|
|
||||||
|
|
||||||
# Markdown page example
|
|
||||||
|
|
||||||
You don't need React to write simple standalone pages.
|
|
BIN
static/img/homelab.png
Normal file
BIN
static/img/homelab.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
Loading…
x
Reference in New Issue
Block a user