mirror of
https://github.com/flynx/proxmox-utils.git
synced 2026-01-13 06:45:39 +00:00
Compare commits
15 Commits
fc7d23b860
...
f3d3b3fe32
| Author | SHA1 | Date | |
|---|---|---|---|
| f3d3b3fe32 | |||
| 39b42883fc | |||
| 66b2b7ea7f | |||
| b7f56623d9 | |||
| aeb2bbde82 | |||
| c8c09ce8d5 | |||
| 8e8c89f50a | |||
| a844845c4f | |||
| 752675a5ca | |||
| fb0005e9d1 | |||
| bf30e7714a | |||
| f4c54d2cba | |||
| 12b1029989 | |||
| 78b2932f66 | |||
| ee2f88bf0b |
60
.pct-helpers
60
.pct-helpers
@ -302,33 +302,81 @@ xreadpass(){
|
||||
}
|
||||
|
||||
|
||||
# Like cat but a prettier...
|
||||
#
|
||||
# listFile PATH
|
||||
#
|
||||
listFile(){
|
||||
if [ -e "$1" ] ; then
|
||||
echo "--- $1 ---"
|
||||
cat "$1"
|
||||
echo '---'
|
||||
else
|
||||
echo "$FUNCNAME: $1: No such file or directory."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# Review changes in PATH.new, then edit/apply changes to PATH
|
||||
#
|
||||
# reviewApplyChanges PATH
|
||||
# reviewApplyChanges PATH [apply|edit|skip]
|
||||
#
|
||||
#
|
||||
# NOTE: if changes are not applied this will return non-zero making this
|
||||
# usable in conditionals...
|
||||
reviewApplyChanges(){
|
||||
local file=$1
|
||||
if ! [ -e "$file".new ] ; then
|
||||
echo "$FUNCNAME: $1: No such file or directory."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# default option...
|
||||
local dfl=
|
||||
local a=a
|
||||
local e=e
|
||||
local s=s
|
||||
case "${2,,}" in
|
||||
a|apply)
|
||||
a=A
|
||||
dfl=a
|
||||
;;
|
||||
e|edit)
|
||||
e=E
|
||||
dfl=e
|
||||
;;
|
||||
s|skip)
|
||||
s=S
|
||||
dfl=s
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "# Review updated: ${file}.new:"
|
||||
@ cat ${file}.new
|
||||
echo '---'
|
||||
listFile ${file}.new
|
||||
local res
|
||||
while true ; do
|
||||
read -ep "# [a]pply, [e]dit, [s]kip? " res
|
||||
read -ep "# [$a]pply, [$e]dit, [$s]kip? " res
|
||||
if [ -z $res ] ; then
|
||||
if [ -z $dfl ] ; then
|
||||
continue
|
||||
fi
|
||||
res=$dfl
|
||||
fi
|
||||
case "${res,,}" in
|
||||
a|apply)
|
||||
break
|
||||
;;
|
||||
e|edit)
|
||||
${EDITOR} "${file}.new"
|
||||
listFile ${file}.new
|
||||
;;
|
||||
s|skip)
|
||||
echo "# file saved as: ${file}.new"
|
||||
echo "# Changes kept as: ${file}.new"
|
||||
return 1
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: unknown command: \"$res\"" >&2
|
||||
echo "ERROR: Unknown command: \"$res\"" >&2
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
7
Makefile
7
Makefile
@ -10,7 +10,7 @@
|
||||
#
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
EDITOR ?= vim
|
||||
EDITOR ?= nano
|
||||
|
||||
|
||||
# CTs...
|
||||
@ -94,7 +94,10 @@ bootstrap-clean: host-bootstrap-clean
|
||||
|
||||
# Finalize: reconect admin port/bridge correctly...
|
||||
.PHONY: finalize
|
||||
finalize: bootstrap-clean gate-bootstrap-clean
|
||||
finalize: gate-bootstrap-clean
|
||||
# cleanup: stage 1...
|
||||
make host-bootstrap-clean
|
||||
# cleanup: stage 2...
|
||||
make host-bootstrap-clean
|
||||
|
||||
|
||||
|
||||
93
README.md
93
README.md
@ -3,18 +3,20 @@
|
||||
A set of scripts for automating setup and tasks in proxmox.
|
||||
|
||||
## TODO
|
||||
- revise defaults
|
||||
- CT updates
|
||||
- backup/restore
|
||||
- mail
|
||||
- which is better?
|
||||
- Makefile (a-la ./wireguard/templates/root/Makefile)
|
||||
- shell (a-la ./shadow/templates/root/update-shadowsocks.sh)
|
||||
- separate templates/assets into distribution and user directories
|
||||
...this is needed to allow the user to change the configs without the
|
||||
fear of them being overwritten by git (similar to how config is handlerd)
|
||||
- might be a good idea to export a specific ct script that can be used
|
||||
for updates for that ct
|
||||
- which is better?
|
||||
- Makefile (a-la wireguard)
|
||||
- shell (a-la shadow)
|
||||
- ct updates
|
||||
- backup/restore
|
||||
- mail
|
||||
|
||||
|
||||
<!-- START doctoc -->
|
||||
<!-- END doctoc -->
|
||||
|
||||
|
||||
|
||||
## Motivation
|
||||
@ -116,6 +118,9 @@ Three ways of access to the ADMIN network are provided:
|
||||
|
||||
Install Proxmox and connect it to your device/network.
|
||||
|
||||
Proxmox will need to have access to the internet to download assets and
|
||||
updates.
|
||||
|
||||
|
||||
#### Notes
|
||||
|
||||
@ -132,6 +137,13 @@ This setup will use three IP addresses:
|
||||
|
||||
### Semi-automated setup
|
||||
|
||||
Open a terminal on the host (`ssh` or via the UI).
|
||||
|
||||
Optionally, set a desired default editor via:
|
||||
```shell
|
||||
export EDITOR=nano
|
||||
```
|
||||
|
||||
Download the [`bootstrap.sh`](./scripts/bootstrap.sh) script and execute it:
|
||||
```shell
|
||||
curl 'https://raw.githubusercontent.com/flynx/proxmox-utils/refs/heads/master/scripts/bootstrap.sh' | sudo bash
|
||||
@ -162,22 +174,69 @@ make finalize
|
||||
```
|
||||
|
||||
This will
|
||||
- detach the host from any external ports and make it accessible only
|
||||
from the internal network.
|
||||
See: [Architecture](#architecture) and [Bootstrapping](#bootstrapping)
|
||||
- setup firewall rules.
|
||||
- Setup firewall rules.
|
||||
Note that the firewall will not be enabled, this should be done manually
|
||||
after rule review.
|
||||
|
||||
- Detach the host from any external ports and make it accessible only
|
||||
from the internal network.
|
||||
See: [Architecture](#architecture) and [Bootstrapping](#bootstrapping)
|
||||
|
||||
This will break the ssh connection when done, reconnect via the WAN port
|
||||
to continue (see: [Accessing the host](#accessing-the-host)), or connect
|
||||
directly to the ADMIN port (DHCP) and ssh into `$HOST_ADMIN_IP` (default: 10.0.0.254).
|
||||
|
||||
|
||||
_Note that the ADMIN port is configured for direct connections only (DHCP),
|
||||
connecting it to a configured network can lead to unexpected behavior._
|
||||
|
||||
*Note that the ADMIN port is configured for direct connections only (DHCP),
|
||||
connecting it to a configured network can lead to unexpected behavior.*
|
||||
|
||||
|
||||
#### Accessing the host
|
||||
|
||||
The simplest way is to connect to `wireguard` VPN and open http://pve.adm:8006
|
||||
in a browser (a profile was created during the setup process and stored
|
||||
in the `/root/clients/` directory on the `wireguard` CT).
|
||||
|
||||
The second approach is to `ssh` to either:
|
||||
|
||||
```shell
|
||||
ssh -p 23 <user>@<WAN_IP>
|
||||
```
|
||||
|
||||
or:
|
||||
```shell
|
||||
ssh <user>@<WAN_SSH_IP>
|
||||
```
|
||||
|
||||
The later will also work if the `gate` CT is down or not accessible.
|
||||
|
||||
|
||||
And from the `ssh` CT:
|
||||
```shell
|
||||
ssh root@pve
|
||||
```
|
||||
|
||||
_WARNING: NEVER store any ssh keys on the `ssh` CT, use `ssh-agent` instead!_
|
||||
|
||||
|
||||
|
||||
#### Configuration
|
||||
|
||||
XXX
|
||||
|
||||
The following CT's interfaces can not be configured in the Proxmox UI:
|
||||
- `gate`
|
||||
- `ns`
|
||||
- `nextcloud`
|
||||
- `wireguard`
|
||||
|
||||
This is done mostly to keep Proxmox from touching the `hostname $(hostname)`
|
||||
directive (used by the DNS server to assigned predefined IP's) and in
|
||||
the case of `gate` and `wireguard` to keep it from touching the additional
|
||||
bridges or interfaces defined.
|
||||
(XXX this restriction may be lifted in the future)
|
||||
|
||||
|
||||
|
||||
#### Setup additional services
|
||||
|
||||
@ -212,6 +271,8 @@ XXX traefik rules
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Manual setup
|
||||
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#------------------------------------------------------------------------
|
||||
#----------------------------------------------------------------------
|
||||
#
|
||||
# Global config file
|
||||
#
|
||||
@ -16,7 +16,68 @@
|
||||
# It is not recomended to set passwords here or in other config files.
|
||||
#
|
||||
#
|
||||
#------------------------------------------------------------------------
|
||||
#----------------------------------------------------------------------
|
||||
# These options need to be revised or changed...
|
||||
# (remove "DFL_" prefix to disable promting)
|
||||
#
|
||||
|
||||
# Domain and email configuration
|
||||
#
|
||||
DFL_DOMAIN=example.com
|
||||
DFL_EMAIL=user@example.com
|
||||
|
||||
|
||||
# Network configuration...
|
||||
#
|
||||
# NOTE: it is simpler to statically assign these than to configure DHCP
|
||||
# plus port forewarding to the dynamically assigned IP.
|
||||
# NOTE: if installing on a different network than the target, these can
|
||||
# be changed for target deployment in:
|
||||
# - gate CT's /etc/network/interfaces (NOT in the Proxmox UI)
|
||||
# - ssh CT's network configuration (Proxmox UI)
|
||||
DFL_WAN_IP=192.168.1.101/24
|
||||
DFL_WAN_GATE=192.168.1.252
|
||||
|
||||
# IP used for fail-safe conection to the ADMIN network
|
||||
DFL_WAN_SSH_IP=192.168.1.102/24
|
||||
|
||||
|
||||
# Web app/service domain configuration
|
||||
#
|
||||
# Here two optional variables are provided per service:
|
||||
# - <SERVICE>_DOMAIN=...
|
||||
# Overrides the $DOMAIN option above for <SERVICE>
|
||||
# - <SERVICE>_SUBDOMAIN=...
|
||||
# Sets the subdomain of $DOMAIN (or $<SERVICE>_DOMAIN) for <SERVICE>
|
||||
|
||||
# Nextcloud
|
||||
#NEXTCLOUD_DOMAIN=
|
||||
NEXTCLOUD_SUBDOMAIN=nc.
|
||||
|
||||
# Gitea
|
||||
#GITEA_DOMAIN=
|
||||
#GITEA_SUBDOMAIN=git.
|
||||
|
||||
|
||||
# Extra options passed to each CT when created.
|
||||
#
|
||||
# This can be used for passing in ssh keys, etc...
|
||||
#
|
||||
# see:
|
||||
# man pct
|
||||
#
|
||||
# Example:
|
||||
# DFL_PCT_EXTRA="--ssh-public-keys /path/to/autohrized_keys"
|
||||
#
|
||||
DFL_PCT_EXTRA=SKIP
|
||||
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
#
|
||||
# Options afetr this point are sane defaults and in the general case
|
||||
# can be left as-is.
|
||||
#
|
||||
|
||||
# Bootsrap configuration...
|
||||
#
|
||||
@ -37,70 +98,21 @@ BOOTSTRAP_BRIDGE=0
|
||||
# bridges with numbers greater than X (10 in the example below)
|
||||
#
|
||||
# Example:
|
||||
# WAN_BRIDGE=0
|
||||
# ADMIN_BRIDGE=3
|
||||
# LAN_BRIDGE=10
|
||||
# ADMIN_BRIDGE=_admin
|
||||
# WAN_BRIDGE=_wan
|
||||
# LAN_BRIDGE=_lan
|
||||
#
|
||||
ADMIN_BRIDGE=_admin
|
||||
WAN_BRIDGE=_wan
|
||||
LAN_BRIDGE=_lan
|
||||
|
||||
|
||||
# NOTE: it is simpler to statically assign these than to configure dhcp
|
||||
# plus port forewarding to the dynamically assigned IP.
|
||||
DFL_WAN_IP=192.168.1.101/24
|
||||
DFL_WAN_GATE=192.168.1.252
|
||||
|
||||
DFL_WAN_SSH_IP=192.168.1.102/24
|
||||
|
||||
|
||||
# Domain and email configuration
|
||||
#
|
||||
DOMAIN=example.com
|
||||
EMAIL=user@example.com
|
||||
|
||||
|
||||
# Web app/service domain configuration
|
||||
#
|
||||
# Here two optional variables are provided per service:
|
||||
# - <SERVICE>_DOMAIN=...
|
||||
# Overrides the $DOMAIN option above for <SERVICE>
|
||||
# - <SERVICE>_SUBDOMAIN=...
|
||||
# Sets the subdomain of $DOMAIN (or $<SERVICE>_DOMAIN) for <SERVICE>
|
||||
#
|
||||
|
||||
# Nextcloud
|
||||
#NEXTCLOUD_DOMAIN=
|
||||
NEXTCLOUD_SUBDOMAIN=nc.
|
||||
|
||||
# Gitea
|
||||
#GITEA_DOMAIN=
|
||||
#GITEA_SUBDOMAIN=git.
|
||||
|
||||
|
||||
# Extra options passed to each CT created.
|
||||
#
|
||||
# This can be used for passing in ssh keys, etc...
|
||||
#
|
||||
# see:
|
||||
# man pct
|
||||
#
|
||||
# Example:
|
||||
# DFL_PCT_EXTRA="--ssh-public-keys /path/to/autohrized_keys"
|
||||
#
|
||||
DFL_PCT_EXTRA=SKIP
|
||||
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
#
|
||||
# Options afetr this point are sane defaults and in the general case
|
||||
# can be left as-is.
|
||||
#
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
# host
|
||||
HOST_ADMIN_IP=10.0.0.254/24
|
||||
|
||||
|
||||
# Nameserver
|
||||
NS_HOSTNAME=ns
|
||||
NS_ID=100
|
||||
@ -110,6 +122,7 @@ NS_LAN_IP=10.1.1.1/24
|
||||
RESERVE_NS_ID=101
|
||||
TEMPLATE_NS_ID=200
|
||||
|
||||
|
||||
# Gateway / Reverse proxy
|
||||
GATE_HOSTNAME=gate
|
||||
GATE_ID=110
|
||||
@ -120,4 +133,5 @@ RESERVE_GATE_ID=111
|
||||
TEMPLATE_GATE_ID=210
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
@ -25,8 +25,8 @@ RAM=128
|
||||
SWAP=$RAM
|
||||
DRIVE=0.5
|
||||
|
||||
DFL_WAN_IP=${DFL_WAN_IP}
|
||||
DFL_WAN_GATE=${DFL_WAN_GATE}
|
||||
#DFL_WAN_IP=${DFL_WAN_IP}
|
||||
#DFL_WAN_GATE=${DFL_WAN_GATE}
|
||||
|
||||
# XXX revise...
|
||||
DFL_ADMIN_IP=${GATE_ADMIN_IP:=${DFL_ADMIN_IP:=10.0.0.2/24}}
|
||||
|
||||
50
host/make.sh
50
host/make.sh
@ -49,9 +49,23 @@ BRIDGES_TPL=${BRIDGES_TPL:-bridges.tpl}
|
||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
# Bootstrap...
|
||||
|
||||
# cleanup...
|
||||
if ! [ -z $BOOTSTRAP_CLEAN ] ; then
|
||||
@ cp "$INTERFACES"{,.bak}
|
||||
|
||||
__finalize(){
|
||||
if reviewApplyChanges "$INTERFACES" apply ; then
|
||||
# XXX this must be done in nohup to avoid breaking on connection lost...
|
||||
if ! @ ifreload -a ; then
|
||||
# reset settings back if ifreload fails...
|
||||
@ cp "$INTERFACES"{.bak,}
|
||||
@ ifreload -a
|
||||
fi
|
||||
fi
|
||||
# clear self to avoid a second deffered execution...
|
||||
unset -f __finalize
|
||||
}
|
||||
|
||||
# stage 1: bootstrap -> clean
|
||||
if [ -e "$INTERFACES".clean ] ; then
|
||||
@ mv "$INTERFACES"{.clean,.new}
|
||||
@ -62,6 +76,9 @@ if ! [ -z $BOOTSTRAP_CLEAN ] ; then
|
||||
DFL_DNS=1
|
||||
DFL_FIREWALL=SKIP
|
||||
|
||||
# NOTE: in general this is non-destructive and can be done inline.
|
||||
__finalize
|
||||
|
||||
# stage 2: clean -> final
|
||||
elif [ -e "$INTERFACES".final ] ; then
|
||||
@ mv "$INTERFACES"{.final,.new}
|
||||
@ -72,6 +89,8 @@ if ! [ -z $BOOTSTRAP_CLEAN ] ; then
|
||||
DFL_DNS=SKIP
|
||||
DFL_FIREWALL=1
|
||||
|
||||
# NOTE: __finalize is deferred to just before reboot...
|
||||
|
||||
REBOOT=1
|
||||
|
||||
# done
|
||||
@ -79,15 +98,6 @@ if ! [ -z $BOOTSTRAP_CLEAN ] ; then
|
||||
exit
|
||||
fi
|
||||
|
||||
if reviewApplyChanges "$INTERFACES" ; then
|
||||
# XXX this must be done in nohup to avoid breaking on connection lost...
|
||||
if ! @ ifreload -a ; then
|
||||
# reset settings back if ifreload fails...
|
||||
@ cp "$INTERFACES"{.bak,}
|
||||
@ ifreload -a
|
||||
fi
|
||||
fi
|
||||
|
||||
# Bootstrap...
|
||||
elif ! [ -z $BOOTSTRAP ] ; then
|
||||
DFL_BOOTSTRAP_PORT=${DFL_BOOTSTRAP_PORT:-none}
|
||||
@ -107,20 +117,20 @@ fi
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
# System...
|
||||
# system...
|
||||
if xreadYes "# Update system?" UPDATE ; then
|
||||
@ apt update
|
||||
@ apt upgrade
|
||||
fi
|
||||
|
||||
|
||||
# Tools...
|
||||
# tools...
|
||||
if xreadYes "# Install additional apps?" APPS ; then
|
||||
@ apt install ${SOFTWARE[@]}
|
||||
fi
|
||||
|
||||
|
||||
# Bridges...
|
||||
# bridges...
|
||||
if xreadYes "# Create bridges?" BRIDGES ; then
|
||||
xread "WAN port: " WAN_PORT
|
||||
xread "ADMIN port: " ADMIN_PORT
|
||||
@ -203,7 +213,7 @@ if xreadYes "# Create bridges?" BRIDGES ; then
|
||||
fi
|
||||
|
||||
# interfaces
|
||||
if reviewApplyChanges "$INTERFACES" ; then
|
||||
if reviewApplyChanges "$INTERFACES" apply ; then
|
||||
# XXX this must be done in nohup to avoid breaking on connection lost...
|
||||
if ! @ ifreload -a ; then
|
||||
# reset settings back if ifreload fails...
|
||||
@ -221,7 +231,7 @@ if xreadYes "# Update /etc/hosts?" HOSTS ; then
|
||||
@ sed -i \
|
||||
-e 's/^[^#].* \(pve.local.*\)$/'${HOST_ADMIN_IP/\/*}' \1/' \
|
||||
/etc/hosts.new
|
||||
reviewApplyChanges /etc/hosts
|
||||
reviewApplyChanges /etc/hosts apply
|
||||
fi
|
||||
|
||||
|
||||
@ -240,7 +250,7 @@ if xreadYes "# Update DNS?" DNS ; then
|
||||
build
|
||||
file=/etc/resolv.conf
|
||||
@ cp "staging/${file}" "${file}".new
|
||||
reviewApplyChanges "${file}"
|
||||
reviewApplyChanges "${file}" apply
|
||||
fi
|
||||
|
||||
|
||||
@ -249,7 +259,7 @@ if xreadYes "# Update firewall rules?" FIREWALL ; then
|
||||
build
|
||||
file=/etc/pve/firewall/cluster.fw
|
||||
@ cp "staging/${file}" "${file}".new
|
||||
reviewApplyChanges "${file}"
|
||||
reviewApplyChanges "${file}" apply
|
||||
fi
|
||||
|
||||
|
||||
@ -257,6 +267,14 @@ showNotes
|
||||
echo "# Done."
|
||||
|
||||
|
||||
# finalize...
|
||||
if [[ $( type -t __finalize ) == "function" ]] ; then
|
||||
echo "# Finalizing ${INTERFACES}..."
|
||||
__finalize
|
||||
fi
|
||||
|
||||
|
||||
# reboot...
|
||||
if ! [ -z $REBOOT ] ; then
|
||||
echo "# Rebooting..."
|
||||
@ reboot
|
||||
|
||||
@ -24,10 +24,10 @@ readConfig
|
||||
DFL_ID=${DFL_ID:=120}
|
||||
DFL_CTHOSTNAME=${DFL_CTHOSTNAME:=ssh}
|
||||
|
||||
DFL_CORES=${DFL_CORES:=1}
|
||||
DFL_RAM=${DFL_RAM:=1024}
|
||||
DFL_SWAP=${DFL_SWAP:=${DFL_RAM}}
|
||||
DFL_DRIVE=${DFL_DRIVE:=16}
|
||||
DFL_CORES=${DFL_SSH_CORES:=1}
|
||||
DFL_RAM=${DFL_SSH_RAM:=512}
|
||||
DFL_SWAP=${DFL_SSH_SWAP:=${DFL_RAM}}
|
||||
DFL_DRIVE=${DFL_SSH_DRIVE:=16}
|
||||
|
||||
WAN_IP=SKIP
|
||||
WAN_GATE=SKIP
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user