Skip to content

Debian as guest in Proxmox

Template to install quickly a functional Debian VM inside Proxmox VE.

Proxmox Settings

First step you must fix MAC ADDRESS on Proxmox-GUI.

  • Select your VM's
  • Select Hardware tab and go to Network Device
  • Clic to edit and add your MAC ADDRESS

Debian installation

We use the official netboot minimalist iso from Debian.

You can found the iso here.


  • LANG = English UTF8
  • Country = Belgium
  • Keyboard = Belgian
  • Timezone = Europe/Brussels



In case or you have only one IP you can use masquerading

If you choose to work with ip failover you must look on your DNS provider to obtain an valid IP address and domain name because every VM must have his own ip and mac address just like a real server.

In my case I work with OVH & SoYouStart solutions.

So, in our set up every VM's must have his own IP failover.

Example if you have IP

The settings that should be applied

  • IP to
  • Netmask to
  • Gateway to
  • Nameserver to

If these settings aren't set up you can't access to internet.

Ubuntu server case

Ubuntu have other behavior to configure his network as you can see beneath with same example.

You must set during installation process

  • Subnet
  • Address
  • Gateway
  • NameServers,,

Disk and boot loader

I have one disk it is /dev/sda with size of 30Gio.

My partitions schema

  • /dev/sda1 size = 512MB formated in ext2 mounted under /boot.
  • /dev/sda2 size = all space left. You must configure LVM and add sda2 in a VolumeGroup. I have called my VG systemdeb.
  • /dev/systemdeb/swap = 1Go formated in swap.
  • /dev/systemdeb/root = 10Go formated in XFS.
  • /dev/systemdeb/var = 15Go formated in XFS.
  • /dev/systemdeb/tmp = 3Go formated in XFS.

Mirror, Software settings & Grub install

  • Mirror select
  • On software select => SSH server & standard system utilities
  • Install the boot loader on /dev/sda1 (if you have more than one disk attached to the vm check with lsblk or something like that to verify on which disk make the installation)

When it's done reboot.

Set up Debian

System update + root pass change

At this time we can't login via SSH so go by Proxmox-GUI shell and log in root.

apt update && apt full-upgrade -y
passwd root
passwd michael (user created during the install process)
apt install qemu-guest-agent

For root & user password it is highly recommend to use an password generator like builtin in buttercup/keepass software with 24 characters. (char + special char + digits + underline/score no blank space)


Reboot the VM to apply support of qemu-guest-agent.

Software base

To work on my server I use every time same tools to mana.

apt install sudo net-tools netcat ccze ranger htop git vim zsh ncdu dfc lftp curl wget rsync mlocate dirmngr multitail lnav iptraf-ng

Shell set up and improvement

To improve the work flow with the the shell we use ZSH with OhMyZsh framework. It is easy to use, configure and deploy.

Get OhMyZsh

We donwload the script to install the framework

sh -c "$(wget -O -)"

ZSHRC improvement


We modify our .zshrc but take for export ZSH value you must adapt it to your own installation. Adapt the path to the VM user.

Edit our ~/.zshrc as beneath

# Path to your oh-my-zsh installation.
export ZSH="/home/$USERNAME/.oh-my-zsh" #adapt to your installation

# looking in ~/.oh-my-zsh/themes/

# Uncomment the following line to use case-sensitive completion.

# Uncomment the following line to use hyphen-insensitive completion. Case
# sensitive completion must be off. _ and - will be interchangeable.

# Uncomment the following line to disable bi-weekly auto-update checks.

# Uncomment the following line to change how often to auto-update (in days).

# Uncomment the following line to disable colors in ls.

# Uncomment the following line to disable auto-setting terminal title.

# Uncomment the following line to enable command auto-correction.

# Uncomment the following line to display red dots whilst waiting for completion.

# Uncomment the following line if you want to change the command execution time
# stamp shown in the history command output.
# The optional three formats: "mm/dd/yyyy"|""|"yyyy-mm-dd"

# Would you like to use another custom folder than $ZSH/custom?
# ZSH_CUSTOM=/path/to/new-custom-folder

# Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)
# Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.

source $ZSH/

# User configuration
export MANPATH="/usr/local/man:$MANPATH"

# You may need to manually set your language environment
export LANG=en_US.UTF-8

# Preferred editor for local and remote sessions
if [[ -n $SSH_CONNECTION ]]; then
  export EDITOR='vim'
  export EDITOR='nano'

# Compilation flags
export ARCHFLAGS="-arch x86_64"

# ssh
export SSH_KEY_PATH="~/.ssh/rsa_id"

# Personnal alias #

# System
alias sysctlres="sudo systemctl restart"
alias sysctlrel="sudo systemctl reload"
alias sysctlstart="sudo systemctl start"
alias sysctlstop="sudo systemctl stop"
alias sysctlstat="sudo systemctl status"
alias sysctlist="sudo systemctl list-units -t service"
alias sysctlupd="sudo apt update && apt list --upgradable"
alias sysctlupgr="sudo apt full-upgrade -y"

# Tools
alias netstat="netstat -plntu"
alias netstatfull="netstat -nlapute"

VIMRC improvement

In server environment I use vim to edit my conf files so go to edit our ~/.vimrc as beneath

syntax on
filetype indent on

set background=dark
set t_Co=256
set smartindent
set number
set showcmd
set showmode
set nobackup
set nowritebackup
set hlsearch
set autoindent
set ignorecase
set laststatus=2

" Remember last position of the cursor
augroup resCur
  autocmd BufReadPost * call setpos(".", getpos("'\""))
augroup END

  " Git Branch Info
function! GitBranch()
  return system("git rev-parse --abbrev-ref HEAD 2>/dev/null | tr -d '\n'")

" Line Status
  function! StatuslineGit()
    let l:branchname = GitBranch()
      return strlen(l:branchname) > 0?'  '.l:branchname.' ':''

      set statusline=
      set statusline+=%#PmenuSel#
      set statusline+=%{StatuslineGit()}
      set statusline+=%#LineNr#
      set statusline+=\ %f
      set statusline+=%m\
      set statusline+=%=
      set statusline+=%#CursorColumn#
      set statusline+=\ %y
      set statusline+=\ %{&fileencoding?&fileencoding:&encoding}
      set statusline+=\[%{&fileformat}\]
      set statusline+=\ %p%%
      set statusline+=\ %l:%c
      set statusline+=\
      set statusline=%<%F%h%m%r%h%w%y\ %{&ff}\ %{strftime(\"%c\",getftime(expand(\"%:p\")))}%=\lin:%l\,%L\ col:%c%V\ pos:%o\ ascii:%b\ %P

User & group management

In our case we have deploy the Debian ISO on our VM. During his installation process debian have create two users, the root and your $USER.

By default Debian don't have sudo already installed so you must use su root to have root privilege. Isn't the good way.

Before on our tutorial we have install sudo package, we just give sudo permission to our $USER.

Add our user to sudo group

usermod -aG sudo $USER

Verify on which group our user exist

id $USER

Normally you will have simillary output

uid=1000($USERadm) gid=1000($USERadm) groups=1000($USERadm),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),108(netdev)

Delete your user from these groups

deluser $USER cdrom
deluser $USER floppy
deluser $USER netdev
deluser $USER plugdev
deluser $USER audio
deluser $USER video
deluser $USER dip

Change the behavior of SWAP

By default linux starts using your swap memory as soon as you exceed 40% of your RAM usage.

This is the default behavior and we will change it to avoid unnecessary performance losses.

Edit your /etc/sysctl.conf

and add vm.swappiness = 10 at the end of the file.

After the reboot your system start to use the swap when is reach 90% of the total memory.

Set up SSH

First, save your actual sshd_config to avoid big issue

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

When it's saved edit sshd_config as beneath

# What ports, IPs and protocols we listen for
Port 65022
# Use these options to restrict which interfaces/protocols sshd will bind to
ListenAddress ::
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes

# Lifetime and size of ephemeral version 1 server key

# Logging
SyslogFacility AUTH
LogLevel INFO

# Authentication:
LoginGraceTime 120
PermitRootLogin prohibit-password
StrictModes yes

#AuthorizedKeysFile %h/.ssh/authorized_keys

# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# For this to work you will also need host keys in /etc/ssh_known_hosts
# similar for protocol version 2
HostbasedAuthentication no
# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes

# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no

# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no

# Change to no to disable tunnelled clear text passwords
PasswordAuthentication yes

# Kerberos options
#KerberosAuthentication no
#KerberosGetAFSToken no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes

# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes

X11Forwarding no
#X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
#UseLogin no

#MaxStartups 10:30:60
#Banner /etc/

# Allow client to pass locale environment variables

Subsystem sftp /usr/lib/openssh/sftp-server

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes

Restart sshd.service and verify if everything works fine

systemctl restart sshd.service && systemctl status sshd.service
netstat -nlapute #normally will display an list open ports on your machine

The end

Now you have a base VM to works and install every services what you need. You can continue by improvement the security configuration of SSH (rsa key usage by example), set up the firewall, install Fail2Ban, a webserver by nginx/apache2, ... Your imagination is the limit ;-) !